WebKit Bugzilla
Attachment 348459 Details for
Bug 188940
: [WHLSL] Implement texture types
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
WIP
bug-188940-20180829182337.patch (text/plain), 54.62 KB, created by
Myles C. Maxfield
on 2018-08-29 18:23:38 PDT
(
hide
)
Description:
WIP
Filename:
MIME Type:
Creator:
Myles C. Maxfield
Created:
2018-08-29 18:23:38 PDT
Size:
54.62 KB
patch
obsolete
>Subversion Revision: 235490 >diff --git a/Tools/ChangeLog b/Tools/ChangeLog >index 3ad6772a8a07b5ea6819e7bb50bf6e7ba66efd99..8b0eaa9be1de0596f6d06b4ca6b2554b9626a570 100644 >--- a/Tools/ChangeLog >+++ b/Tools/ChangeLog >@@ -1,3 +1,36 @@ >+2018-08-29 Myles C. Maxfield <mmaxfield@apple.com> >+ >+ [WHLSL] Implement texture types >+ https://bugs.webkit.org/show_bug.cgi?id=188940 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * WebGPUShadingLanguageRI/All.js: >+ * WebGPUShadingLanguageRI/Intrinsics.js: >+ (Intrinsics.): >+ (Intrinsics): >+ * WebGPUShadingLanguageRI/SPIRV.html: >+ * WebGPUShadingLanguageRI/StandardLibrary.js: >+ (let.standardLibrary): >+ * WebGPUShadingLanguageRI/Test.html: >+ * WebGPUShadingLanguageRI/Test.js: >+ (makeSampler): >+ (make1DTexture): >+ (make1DTextureArray): >+ (make2DTexture): >+ (make2DTextureArray): >+ (make3DTexture): >+ (makeTextureCube): >+ (makeRW1DTexture): >+ (makeRW1DTextureArray): >+ (makeRW2DTexture): >+ (makeRW2DTextureArray): >+ (makeRW3DTexture): >+ * WebGPUShadingLanguageRI/TextureOperations.js: Added. >+ (textureLoad): >+ (textureStore): >+ * WebGPUShadingLanguageRI/index.html: >+ > 2018-08-29 Jer Noble <jer.noble@apple.com> > > Unreviewed test gardening; NowPlayingTest API tests require High Sierra. >diff --git a/Tools/WebGPUShadingLanguageRI/All.js b/Tools/WebGPUShadingLanguageRI/All.js >index 9c2a37150c1e976b926cfbee23437520a8de4a47..cc07fdb516616d328f38445e95a8205392e5da5a 100644 >--- a/Tools/WebGPUShadingLanguageRI/All.js >+++ b/Tools/WebGPUShadingLanguageRI/All.js >@@ -150,6 +150,7 @@ load("SynthesizeStructAccessors.js"); > load("SynthesizeCopyConstructorOperator.js"); > load("SynthesizeDefaultConstructorOperator.js"); > load("TernaryExpression.js"); >+load("TextureOperations.js"); > load("TrapStatement.js"); > load("TypeDef.js"); > load("TypeDefResolver.js"); >diff --git a/Tools/WebGPUShadingLanguageRI/Intrinsics.js b/Tools/WebGPUShadingLanguageRI/Intrinsics.js >index 79f59070daffb55a3f3a70a3b1badb4ce68cd4ef..05f8d0987ae0b77ab5e3fb9d25d68bdaf30b2fa6 100644 >--- a/Tools/WebGPUShadingLanguageRI/Intrinsics.js >+++ b/Tools/WebGPUShadingLanguageRI/Intrinsics.js >@@ -330,7 +330,8 @@ class Intrinsics { > "native typedef sampler", > type => { > this.sampler = type; >- // FIXME: Figure out what to put here. >+ type.size = 1; >+ type.populateDefaultValue = (buffer, offset) => buffer.set(offset, {}); > }); > > for (let textureType of ["Texture1D", "RWTexture1D", "Texture1DArray", "RWTexture1DArray", "Texture2D", "RWTexture2D", "Texture2DArray", "RWTexture2DArray", "Texture3D", "RWTexture3D", "TextureCube"]) { >@@ -339,12 +340,16 @@ class Intrinsics { > `native typedef ${textureType}<${typeArgument}>`, > type => { > this[`${textureType}<${typeArgument}>`] = type; >+ type.size = 1; >+ type.populateDefaultValue = (buffer, offset) => buffer.set(offset, {}); > }); > for (let i = 2; i <= 4; ++i) { > this._map.set( > `native typedef ${textureType}<${typeArgument}${i}>`, > type => { > this[`${textureType}<${typeArgument}${i}>`] = type; >+ type.size = 1; >+ type.populateDefaultValue = (buffer, offset) => buffer.set(offset, {}); > }); > } > } >@@ -356,6 +361,8 @@ class Intrinsics { > `native typedef ${textureType}<${typeArgument}>`, > type => { > this[`${textureType}<${typeArgument}>`] = type; >+ type.size = 1; >+ type.populateDefaultValue = (buffer, offset) => buffer.set(offset, {}); > }); > } > } >@@ -914,6 +921,745 @@ class Intrinsics { > > for (let setter of BuiltinMatrixSetter.functions()) > this._map.set(setter.toString(), func => setter.instantiateImplementation(func)); >+ >+ for (let type of ["bool", "uchar", "ushort", "uint", "char", "short", "int", "half", "float"]) { >+ this._map.set( >+ `native ${type} Sample(Texture1D<${type}>,sampler,float location)`, >+ func => { >+ func.implementation = function([texture, sampler, location]) { >+ } >+ }); >+ this._map.set( >+ `native ${type} Sample(Texture1D<${type}>,sampler,float location,int offset)`, >+ func => { >+ func.implementation = function([texture, sampler, location, offset]) { >+ } >+ }); >+ this._map.set( >+ `native ${type} Load(Texture1D<${type}>,int2 location)`, >+ func => { >+ func.implementation = function ([texture, location]) { >+ return EPtr.box(textureLoad(texture.loadValue(), [location.get(0), location.get(1)])); >+ } >+ }); >+ this._map.set( >+ `native ${type} Load(Texture1D<${type}>,int2 location,int offset)`, >+ func => { >+ func.implementation = function ([texture, location, offset]) { >+ return EPtr.box(textureLoad(texture.loadValue(), [location.get(0), location.get(1) + offset.loadValue()])); >+ } >+ }); >+ this._map.set( >+ `native void GetDimensions(Texture1D<${type}>,uint MipLevel,uint* thread Width,uint* thread NumberOfLevels)`, >+ func => { >+ func.implementation = function([texture, miplevel, width, numberOfLevels]) { >+ let tex = texture.loadValue(); >+ let mipID = miplevel.loadValue(); >+ if (mipID >= tex.length) >+ throw new WTrapError("[load]", "Reading from nonexistant mip level of texture"); >+ width.loadValue().copyFrom(EPtr.box(tex[mipID].length), 1); >+ numberOfLevels.loadValue().copyFrom(EPtr.box(tex.length), 1); >+ } >+ }); >+ >+ this._map.set( >+ `native ${type} Sample(Texture1DArray<${type}>,sampler,float2 location)`, >+ func => { >+ func.implementation = function([texture, sampler, location]) { >+ } >+ }); >+ this._map.set( >+ `native ${type} Sample(Texture1DArray<${type}>,sampler,float2 location,int offset)`, >+ func => { >+ func.implementation = function([texture, sampler, location, offset]) { >+ } >+ }); >+ this._map.set( >+ `native ${type} Load(Texture1DArray<${type}>,int3 location)`, >+ func => { >+ func.implementation = function ([texture, location]) { >+ return EPtr.box(textureLoad(texture.loadValue(), [location.get(0), location.get(1), location.get(2)])); >+ } >+ }); >+ this._map.set( >+ `native ${type} Load(Texture1DArray<${type}>,int3 location,int offset)`, >+ func => { >+ func.implementation = function ([texture, location, offset]) { >+ return EPtr.box(textureLoad(texture.loadValue(), [location.get(0), location.get(1), location.get(2) + offset.loadValue()])); >+ } >+ }); >+ this._map.set( >+ `native void GetDimensions(Texture1DArray<${type}>,uint MipLevel,uint* thread Width,uint* thread Elements,uint* thread NumberOfLevels)`, >+ func => { >+ func.implementation = function([texture, miplevel, width, elements, numberOfLevels]) { >+ let tex = texture.loadValue(); >+ let mipID = miplevel.loadValue(); >+ if (tex.length == 0) >+ throw new WTrapError("[load]", "No elements in the texture array"); >+ if (mipID >= tex[0].length) >+ throw new WTrapError("[load]", "Reading from nonexistant mip level of texture"); >+ width.loadValue().copyFrom(EPtr.box(tex[0][mipID].length), 1); >+ elements.loadValue().copyFrom(EPtr.box(tex.length), 1); >+ numberOfLevels.loadValue().copyFrom(EPtr.box(tex[0].length), 1); >+ } >+ }); >+ >+ this._map.set( >+ `native ${type} Sample(Texture2D<${type}>,sampler,float2 location)`, >+ func => { >+ func.implementation = function([texture, sampler, location]) { >+ } >+ }); >+ this._map.set( >+ `native ${type} Sample(Texture2D<${type}>,sampler,float2 location,int2 offset)`, >+ func => { >+ func.implementation = function([texture, sampler, location, offset]) { >+ } >+ }); >+ this._map.set( >+ `native ${type} SampleBias(Texture2D<${type}>,sampler,float2 location,float Bias)`, >+ func => { >+ func.implementation = function([texture, sampler, location, bias]) { >+ } >+ }); >+ this._map.set( >+ `native ${type} SampleBias(Texture2D<${type}>,sampler,float2 location,float Bias,int2 offset)`, >+ func => { >+ func.implementation = function([texture, sampler, location, bias, offset]) { >+ } >+ }); >+ this._map.set( >+ `native ${type} SampleGrad(Texture2D<${type}>,sampler,float2 location,float2 DDX,float2 DDY)`, >+ func => { >+ func.implementation = function([texture, sampler, location, ddx, ddy]) { >+ } >+ }); >+ this._map.set( >+ `native ${type} SampleGrad(Texture2D<${type}>,sampler,float2 location,float2 DDX,float2 DDY,int2 offset)`, >+ func => { >+ func.implementation = function([texture, sampler, location, ddx, ddy, offset]) { >+ } >+ }); >+ this._map.set( >+ `native ${type} SampleLevel(Texture2D<${type}>,sampler,float2 location,float LOD)`, >+ func => { >+ func.implementation = function([texture, sampler, location, lod]) { >+ } >+ }); >+ this._map.set( >+ `native ${type} SampleLevel(Texture2D<${type}>,sampler,float2 location,float LOD,int2 offset)`, >+ func => { >+ func.implementation = function([texture, sampler, location, lod, offset]) { >+ } >+ }); >+ this._map.set( >+ `native ${type}4 Gather(Texture2D<${type}>,sampler,float2 location)`, >+ func => { >+ func.implementation = function([texture, sampler, location]) { >+ } >+ }); >+ this._map.set( >+ `native ${type}4 Gather(Texture2D<${type}>,sampler,float2 location,int2 offset)`, >+ func => { >+ func.implementation = function([texture, sampler, location, offset]) { >+ } >+ }); >+ this._map.set( >+ `native ${type}4 GatherRed(Texture2D<${type}>,sampler,float2 location)`, >+ func => { >+ func.implementation = function([texture, sampler, location]) { >+ } >+ }); >+ this._map.set( >+ `native ${type}4 GatherRed(Texture2D<${type}>,sampler,float2 location,int2 offset)`, >+ func => { >+ func.implementation = function([texture, sampler, location, offset]) { >+ } >+ }); >+ this._map.set( >+ `native ${type}4 GatherGreen(Texture2D<${type}>,sampler,float2 location)`, >+ func => { >+ func.implementation = function([texture, sampler, location]) { >+ } >+ }); >+ this._map.set( >+ `native ${type}4 GatherGreen(Texture2D<${type}>,sampler,float2 location,int2 offset)`, >+ func => { >+ func.implementation = function([texture, sampler, location, offset]) { >+ } >+ }); >+ this._map.set( >+ `native ${type}4 GatherBlue(Texture2D<${type}>,sampler,float2 location)`, >+ func => { >+ func.implementation = function([texture, sampler, location]) { >+ } >+ }); >+ this._map.set( >+ `native ${type}4 GatherBlue(Texture2D<${type}>,sampler,float2 location,int2 offset)`, >+ func => { >+ func.implementation = function([texture, sampler, location, offset]) { >+ } >+ }); >+ this._map.set( >+ `native ${type}4 GatherAlpha(Texture2D<${type}>,sampler,float2 location)`, >+ func => { >+ func.implementation = function([texture, sampler, location]) { >+ } >+ }); >+ this._map.set( >+ `native ${type}4 GatherAlpha(Texture2D<${type}>,sampler,float2 location,int2 offset)`, >+ func => { >+ func.implementation = function([texture, sampler, location, offset]) { >+ } >+ }); >+ this._map.set( >+ `native ${type} Load(Texture2D<${type}>,int3 location)`, >+ func => { >+ func.implementation = function ([texture, location]) { >+ return EPtr.box(textureLoad(texture.loadValue(), [location.get(0), location.get(1), location.get(2)])); >+ } >+ }); >+ this._map.set( >+ `native ${type} Load(Texture2D<${type}>,int3 location,int2 offset)`, >+ func => { >+ func.implementation = function ([texture, location, offset]) { >+ return EPtr.box(textureLoad(texture.loadValue(), [location.get(0), location.get(1) + offset.get(0), location.get(2) + offset.get(1)])); >+ } >+ }); >+ this._map.set( >+ `native void GetDimensions(Texture2D<${type}>,uint MipLevel,uint* thread Width,uint* thread Height,uint* thread NumberOfLevels)`, >+ func => { >+ func.implementation = function([texture, miplevel, width, height, numberOfLevels]) { >+ let tex = texture.loadValue(); >+ let mipID = miplevel.loadValue(); >+ if (mipID >= tex.length) >+ throw new WTrapError("[load]", "Reading from nonexistant mip level of texture"); >+ if (tex[mipID].length == 0) >+ throw new WTrapError("[load]", "Texture has no rows"); >+ height.loadValue().copyFrom(EPtr.box(tex[mipID].length), 1); >+ width.loadValue().copyFrom(EPtr.box(tex[mipID][0].length), 1); >+ numberOfLevels.loadValue().copyFrom(EPtr.box(tex.length), 1); >+ } >+ }); >+ >+ this._map.set( >+ `native ${type} Sample(Texture2DArray<${type}>,sampler,float3 location)`, >+ func => { >+ func.implementation = function([texture, sampler, location]) { >+ } >+ }); >+ this._map.set( >+ `native ${type} Sample(Texture2DArray<${type}>,sampler,float3 location,int2 offset)`, >+ func => { >+ func.implementation = function([texture, sampler, location, offset]) { >+ } >+ }); >+ this._map.set( >+ `native ${type} SampleBias(Texture2DArray<${type}>,sampler,float3 location,float Bias)`, >+ func => { >+ func.implementation = function([texture, sampler, location, bias]) { >+ } >+ }); >+ this._map.set( >+ `native ${type} SampleBias(Texture2DArray<${type}>,sampler,float3 location,float Bias,int2 offset)`, >+ func => { >+ func.implementation = function([texture, sampler, location, bias, offset]) { >+ } >+ }); >+ this._map.set( >+ `native ${type} SampleGrad(Texture2DArray<${type}>,sampler,float3 location,float2 DDX,float2 DDY)`, >+ func => { >+ func.implementation = function([texture, sampler, location, ddx, ddy]) { >+ } >+ }); >+ this._map.set( >+ `native ${type} SampleGrad(Texture2DArray<${type}>,sampler,float3 location,float2 DDX,float2 DDY,int2 offset)`, >+ func => { >+ func.implementation = function([texture, sampler, location, ddx, ddy, offset]) { >+ } >+ }); >+ this._map.set( >+ `native ${type} SampleLevel(Texture2DArray<${type}>,sampler,float3 location,float LOD)`, >+ func => { >+ func.implementation = function([texture, sampler, location, lod]) { >+ } >+ }); >+ this._map.set( >+ `native ${type} SampleLevel(Texture2DArray<${type}>,sampler,float3 location,float LOD,int2 offset)`, >+ func => { >+ func.implementation = function([texture, sampler, location, lod, offset]) { >+ } >+ }); >+ this._map.set( >+ `native ${type}4 Gather(Texture2DArray<${type}>,sampler,float3 location)`, >+ func => { >+ func.implementation = function([texture, sampler, location]) { >+ } >+ }); >+ this._map.set( >+ `native ${type}4 Gather(Texture2DArray<${type}>,sampler,float3 location,int2 offset)`, >+ func => { >+ func.implementation = function([texture, sampler, location, offset]) { >+ } >+ }); >+ this._map.set( >+ `native ${type}4 GatherRed(Texture2DArray<${type}>,sampler,float3 location)`, >+ func => { >+ func.implementation = function([texture, sampler, location]) { >+ } >+ }); >+ this._map.set( >+ `native ${type}4 GatherRed(Texture2DArray<${type}>,sampler,float3 location,int2 offset)`, >+ func => { >+ func.implementation = function([texture, sampler, location, offset]) { >+ } >+ }); >+ this._map.set( >+ `native ${type}4 GatherGreen(Texture2DArray<${type}>,sampler,float3 location)`, >+ func => { >+ func.implementation = function([texture, sampler, location]) { >+ } >+ }); >+ this._map.set( >+ `native ${type}4 GatherGreen(Texture2DArray<${type}>,sampler,float3 location,int2 offset)`, >+ func => { >+ func.implementation = function([texture, sampler, location, offset]) { >+ } >+ }); >+ this._map.set( >+ `native ${type}4 GatherBlue(Texture2DArray<${type}>,sampler,float3 location)`, >+ func => { >+ func.implementation = function([texture, sampler, location]) { >+ } >+ }); >+ this._map.set( >+ `native ${type}4 GatherBlue(Texture2DArray<${type}>,sampler,float3 location,int2 offset)`, >+ func => { >+ func.implementation = function([texture, sampler, location, offset]) { >+ } >+ }); >+ this._map.set( >+ `native ${type}4 GatherAlpha(Texture2DArray<${type}>,sampler,float3 location)`, >+ func => { >+ func.implementation = function([texture, sampler, location]) { >+ } >+ }); >+ this._map.set( >+ `native ${type}4 GatherAlpha(Texture2DArray<${type}>,sampler,float3 location,int2 offset)`, >+ func => { >+ func.implementation = function([texture, sampler, location, offset]) { >+ } >+ }); >+ this._map.set( >+ `native ${type} Load(Texture2DArray<${type}>,int4 location)`, >+ func => { >+ func.implementation = function ([texture, location]) { >+ return EPtr.box(textureLoad(texture.loadValue(), [location.get(0), location.get(1), location.get(2), location.get(3)])); >+ } >+ }); >+ this._map.set( >+ `native ${type} Load(Texture2DArray<${type}>,int4 location,int2 offset)`, >+ func => { >+ func.implementation = function ([texture, location, offset]) { >+ return EPtr.box(textureLoad(texture.loadValue(), [location.get(0), location.get(1), location.get(2) + offset.get(0), location.get(3) + offset.get(1)])); >+ } >+ }); >+ this._map.set( >+ `native void GetDimensions(Texture2DArray<${type}>,uint MipLevel,uint* thread Width,uint* thread Height,uint* thread Elements,uint* thread NumberOfLevels)`, >+ func => { >+ func.implementation = function([texture, miplevel, width, height, elements, numberOfLevels]) { >+ let tex = texture.loadValue(); >+ let mipID = miplevel.loadValue(); >+ if (tex.length == 0) >+ throw new WTrapError("[load]", "No elements in the texture array"); >+ if (mipID >= tex[0].length) >+ throw new WTrapError("[load]", "Reading from nonexistant mip level of texture"); >+ if (tex[0][mipID].length == 0) >+ throw new WTrapError("[load]", "Texture has no rows"); >+ height.loadValue().copyFrom(EPtr.box(tex[0][mipID].length), 1); >+ width.loadValue().copyFrom(EPtr.box(tex[0][mipID][0].length), 1); >+ elements.loadValue().copyFrom(EPtr.box(tex.length), 1); >+ numberOfLevels.loadValue().copyFrom(EPtr.box(tex[0].length), 1); >+ } >+ }); >+ >+ this._map.set( >+ `native ${type} Sample(Texture3D<${type}>,sampler,float3 location)`, >+ func => { >+ func.implementation = function([texture, sampler, location]) { >+ } >+ }); >+ this._map.set( >+ `native ${type} Sample(Texture3D<${type}>,sampler,float3 location,int3 offset)`, >+ func => { >+ func.implementation = function([texture, sampler, location, offset]) { >+ } >+ }); >+ this._map.set( >+ `native ${type}4 Gather(Texture3D<${type}>,sampler,float3 location)`, >+ func => { >+ func.implementation = function([texture, sampler, location]) { >+ } >+ }); >+ this._map.set( >+ `native ${type}4 Gather(Texture3D<${type}>,sampler,float3 location,int3 offset)`, >+ func => { >+ func.implementation = function([texture, sampler, location, offset]) { >+ } >+ }); >+ this._map.set( >+ `native ${type}4 GatherRed(Texture3D<${type}>,sampler,float3 location)`, >+ func => { >+ func.implementation = function([texture, sampler, location]) { >+ } >+ }); >+ this._map.set( >+ `native ${type}4 GatherRed(Texture3D<${type}>,sampler,float3 location,int3 offset)`, >+ func => { >+ func.implementation = function([texture, sampler, location, offset]) { >+ } >+ }); >+ this._map.set( >+ `native ${type}4 GatherGreen(Texture3D<${type}>,sampler,float3 location)`, >+ func => { >+ func.implementation = function([texture, sampler, location]) { >+ } >+ }); >+ this._map.set( >+ `native ${type}4 GatherGreen(Texture3D<${type}>,sampler,float3 location,int3 offset)`, >+ func => { >+ func.implementation = function([texture, sampler, location, offset]) { >+ } >+ }); >+ this._map.set( >+ `native ${type}4 GatherBlue(Texture3D<${type}>,sampler,float3 location)`, >+ func => { >+ func.implementation = function([texture, sampler, location]) { >+ } >+ }); >+ this._map.set( >+ `native ${type}4 GatherBlue(Texture3D<${type}>,sampler,float3 location,int3 offset)`, >+ func => { >+ func.implementation = function([texture, sampler, location, offset]) { >+ } >+ }); >+ this._map.set( >+ `native ${type}4 GatherAlpha(Texture3D<${type}>,sampler,float3 location)`, >+ func => { >+ func.implementation = function([texture, sampler, location]) { >+ } >+ }); >+ this._map.set( >+ `native ${type}4 GatherAlpha(Texture3D<${type}>,sampler,float3 location,int3 offset)`, >+ func => { >+ func.implementation = function([texture, sampler, location, offset]) { >+ } >+ }); >+ this._map.set( >+ `native ${type} Load(Texture3D<${type}>,int4 location)`, >+ func => { >+ func.implementation = function ([texture, location]) { >+ return EPtr.box(textureLoad(texture.loadValue(), [location.get(0), location.get(1), location.get(2), location.get(3)])); >+ } >+ }); >+ this._map.set( >+ `native ${type} Load(Texture3D<${type}>,int4 location,int3 offset)`, >+ func => { >+ func.implementation = function ([texture, location, offset]) { >+ return EPtr.box(textureLoad(texture.loadValue(), [location.get(0), location.get(1) + offset.get(0), location.get(2) + offset.get(1), location.get(3) + offset.get(2)])); >+ } >+ }); >+ this._map.set( >+ `native void GetDimensions(Texture3D<${type}>,uint MipLevel,uint* thread Width,uint* thread Height,uint* thread Depth,uint* thread NumberOfLevels)`, >+ func => { >+ func.implementation = function([texture, miplevel, width, height, depth, numberOfLevels]) { >+ let tex = texture.loadValue(); >+ let mipID = miplevel.loadValue(); >+ if (mipID >= tex.length) >+ throw new WTrapError("[load]", "Reading from nonexistant mip level of texture"); >+ if (tex[mipID].length == 0) >+ throw new WTrapError("[load]", "Texture has zero depth"); >+ if (tex[mipID][0].length == 0) >+ throw new WTrapError("[load]", "Texture has no rows"); >+ depth.loadValue().copyFrom(EPtr.box(tex[mipID].length), 1); >+ height.loadValue().copyFrom(EPtr.box(tex[mipID][0].length), 1); >+ width.loadValue().copyFrom(EPtr.box(tex[mipID][0][0].length), 1); >+ numberOfLevels.loadValue().copyFrom(EPtr.box(tex.length), 1); >+ } >+ }); >+ >+ this._map.set( >+ `native ${type} Sample(TextureCube<${type}>,sampler,float3 location)`, >+ func => { >+ func.implementation = function([texture, sampler, location]) { >+ } >+ }); >+ this._map.set( >+ `native ${type} SampleBias(TextureCube<${type}>,sampler,float3 location,float Bias)`, >+ func => { >+ func.implementation = function([texture, sampler, location, bias]) { >+ } >+ }); >+ this._map.set( >+ `native ${type} SampleGrad(TextureCube<${type}>,sampler,float3 location,float3 DDX,float3 DDY)`, >+ func => { >+ func.implementation = function([texture, sampler, location, ddx, ddy]) { >+ } >+ }); >+ this._map.set( >+ `native ${type} SampleLevel(TextureCube<${type}>,sampler,float3 location,float LOD)`, >+ func => { >+ func.implementation = function([texture, sampler, location, lod]) { >+ } >+ }); >+ this._map.set( >+ `native ${type}4 Gather(TextureCube<${type}>,sampler,float3 location)`, >+ func => { >+ func.implementation = function([texture, sampler, location]) { >+ } >+ }); >+ this._map.set( >+ `native ${type}4 GatherRed(TextureCube<${type}>,sampler,float3 location)`, >+ func => { >+ func.implementation = function([texture, sampler, location]) { >+ } >+ }); >+ this._map.set( >+ `native ${type}4 GatherGreen(TextureCube<${type}>,sampler,float3 location)`, >+ func => { >+ func.implementation = function([texture, sampler, location]) { >+ } >+ }); >+ this._map.set( >+ `native ${type}4 GatherBlue(TextureCube<${type}>,sampler,float3 location)`, >+ func => { >+ func.implementation = function([texture, sampler, location]) { >+ } >+ }); >+ this._map.set( >+ `native ${type}4 GatherAlpha(TextureCube<${type}>,sampler,float3 location)`, >+ func => { >+ func.implementation = function([texture, sampler, location]) { >+ } >+ }); >+ this._map.set( >+ `native void GetDimensions(TextureCube<${type}>,uint MipLevel,uint* thread Width,uint* thread Height,uint* thread NumberOfLevels)`, >+ func => { >+ func.implementation = function([texture, miplevel, width, height, numberOfLevels]) { >+ let tex = texture.loadValue(); >+ let mipID = miplevel.loadValue(); >+ if (tex.length != 6) >+ throw new WTrapError("[load]", "Cube texture doesn't have 6 faces"); >+ if (mipID >= tex[0].length) >+ throw new WTrapError("[load]", "Reading from nonexistant mip level of texture"); >+ if (tex[0][mipID].length == 0) >+ throw new WTrapError("[load]", "Texture has no rows"); >+ height.loadValue().copyFrom(EPtr.box(tex[0][mipID].length), 1); >+ width.loadValue().copyFrom(EPtr.box(tex[0][mipID][0].length), 1); >+ numberOfLevels.loadValue().copyFrom(EPtr.box(tex[0].length), 1); >+ } >+ }); >+ >+ this._map.set( >+ `native void GetDimensions(RWTexture1D<${type}>,uint* thread Width)`, >+ func => { >+ func.implementation = function([texture, width]) { >+ width.loadValue().copyFrom(EPtr.box(texture.loadValue().length), 1); >+ } >+ }); >+ this._map.set( >+ `native void GetDimensions(RWTexture1D<${type}>,float* thread Width)`, >+ func => { >+ func.implementation = function([texture, width]) { >+ width.loadValue().copyFrom(EPtr.box(texture.loadValue().length), 1); >+ } >+ }); >+ this._map.set( >+ `native ${type} Load(RWTexture1D<${type}>,int location)`, >+ func => { >+ func.implementation = function ([texture, location]) { >+ return EPtr.box(textureLoad(texture.loadValue(), [location.loadValue()])); >+ } >+ }); >+ this._map.set( >+ `native void Store(RWTexture1D<${type}>,${type},uint location)`, >+ func => { >+ func.implementation = function ([texture, value, location]) { >+ textureStore(texture.loadValue(), value.loadValue(), [location.loadValue()]); >+ } >+ }); >+ >+ this._map.set( >+ `native void GetDimensions(RWTexture1DArray<${type}>,uint* thread Width,uint* thread Elements)`, >+ func => { >+ func.implementation = function([texture, width, elements]) { >+ let tex = texture.loadValue(); >+ if (tex.length == 0) >+ throw new WTrapError("[load]", "Texture has no elements"); >+ elements.loadValue().copyFrom(EPtr.box(tex.length), 1); >+ width.loadValue().copyFrom(EPtr.box(tex[0].length), 1); >+ } >+ }); >+ this._map.set( >+ `native void GetDimensions(RWTexture1DArray<${type}>,float* thread Width,uint* thread Elements)`, >+ func => { >+ func.implementation = function([texture, width, elements]) { >+ let tex = texture.loadValue(); >+ if (tex.length == 0) >+ throw new WTrapError("[load]", "Texture has no elements"); >+ elements.loadValue().copyFrom(EPtr.box(tex.length), 1); >+ width.loadValue().copyFrom(EPtr.box(tex[0].length), 1); >+ } >+ }); >+ this._map.set( >+ `native ${type} Load(RWTexture1DArray<${type}>,int2 location)`, >+ func => { >+ func.implementation = function ([texture, location]) { >+ return EPtr.box(textureLoad(texture.loadValue(), [location.get(0), location.get(1)])); >+ } >+ }); >+ this._map.set( >+ `native void Store(RWTexture1DArray<${type}>,${type},uint2 location)`, >+ func => { >+ func.implementation = function ([texture, value, location]) { >+ textureStore(texture.loadValue(), value.loadValue(), [location.get(0), location.get(1)]); >+ } >+ }); >+ >+ this._map.set( >+ `native void GetDimensions(RWTexture2D<${type}>,uint* thread Width,uint* thread Height)`, >+ func => { >+ func.implementation = function([texture, width, height]) { >+ let tex = texture.loadValue(); >+ if (tex.length == 0) >+ throw new WTrapError("[load]", "Texture has no rows"); >+ height.loadValue().copyFrom(EPtr.box(tex.length), 1); >+ width.loadValue().copyFrom(EPtr.box(tex[0].length), 1); >+ } >+ }); >+ this._map.set( >+ `native void GetDimensions(RWTexture2D<${type}>,float* thread Width,float* thread Height)`, >+ func => { >+ func.implementation = function([texture, width, height]) { >+ let tex = texture.loadValue(); >+ if (tex.length == 0) >+ throw new WTrapError("[load]", "Texture has no rows"); >+ height.loadValue().copyFrom(EPtr.box(tex.length), 1); >+ width.loadValue().copyFrom(EPtr.box(tex[0].length), 1); >+ } >+ }); >+ this._map.set( >+ `native ${type} Load(RWTexture2D<${type}>,int2 location)`, >+ func => { >+ func.implementation = function ([texture, location]) { >+ return EPtr.box(textureLoad(texture.loadValue(), [location.get(0), location.get(1)])); >+ } >+ }); >+ this._map.set( >+ `native void Store(RWTexture2D<${type}>,${type},uint2 location)`, >+ func => { >+ func.implementation = function ([texture, value, location]) { >+ textureStore(texture.loadValue(), value.loadValue(), [location.get(0), location.get(1)]); >+ } >+ }); >+ >+ this._map.set( >+ `native void GetDimensions(RWTexture2DArray<${type}>,uint* thread Width,uint* thread Height,uint* thread Elements)`, >+ func => { >+ func.implementation = function([texture, width, height, elements]) { >+ let tex = texture.loadValue(); >+ if (tex.length == 0) >+ throw new WTrapError("[load]", "Texture has no elements"); >+ if (tex[0].length == 0) >+ throw new WTrapError("[load]", "Texture has no rows"); >+ elements.loadValue().copyFrom(EPtr.box(tex.length), 1); >+ height.loadValue().copyFrom(EPtr.box(tex[0].length), 1); >+ width.loadValue().copyFrom(EPtr.box(tex[0][0].length), 1); >+ } >+ }); >+ this._map.set( >+ `native void GetDimensions(RWTexture2DArray<${type}>,float* thread Width,float* thread Height,float* thread Elements)`, >+ func => { >+ func.implementation = function([texture, width, height, elements]) { >+ let tex = texture.loadValue(); >+ if (tex.length == 0) >+ throw new WTrapError("[load]", "Texture has no elements"); >+ if (tex[0].length == 0) >+ throw new WTrapError("[load]", "Texture has no rows"); >+ elements.loadValue().copyFrom(EPtr.box(tex.length), 1); >+ height.loadValue().copyFrom(EPtr.box(tex[0].length), 1); >+ width.loadValue().copyFrom(EPtr.box(tex[0][0].length), 1); >+ } >+ }); >+ this._map.set( >+ `native ${type} Load(RWTexture2DArray<${type}>,int3 location)`, >+ func => { >+ func.implementation = function ([texture, location]) { >+ return EPtr.box(textureLoad(texture.loadValue(), [location.get(0), location.get(1), location.get(2)])); >+ } >+ }); >+ this._map.set( >+ `native void Store(RWTexture2DArray<${type}>,${type},uint3 location)`, >+ func => { >+ func.implementation = function ([texture, value, location]) { >+ textureStore(texture.loadValue(), value.loadValue(), [location.get(0), location.get(1), location.get(2)]); >+ } >+ }); >+ >+ this._map.set( >+ `native void GetDimensions(RWTexture3D<${type}>,uint* thread Width,uint* thread Height,uint* thread Depth)`, >+ func => { >+ func.implementation = function([texture, width, height, depth]) { >+ let tex = texture.loadValue(); >+ if (tex.length == 0) >+ throw new WTrapError("[load]", "Texture has no depth"); >+ if (tex[0].length == 0) >+ throw new WTrapError("[load]", "Texture has no rows"); >+ depth.loadValue().copyFrom(EPtr.box(tex.length), 1); >+ height.loadValue().copyFrom(EPtr.box(tex[0].length), 1); >+ width.loadValue().copyFrom(EPtr.box(tex[0][0].length), 1); >+ } >+ }); >+ this._map.set( >+ `native void GetDimensions(RWTexture3D<${type}>,float* thread Width,float* thread Height,float* thread Depth)`, >+ func => { >+ func.implementation = function([texture, width, height, depth]) { >+ let tex = texture.loadValue(); >+ if (tex.length == 0) >+ throw new WTrapError("[load]", "Texture has no depth"); >+ if (tex[0].length == 0) >+ throw new WTrapError("[load]", "Texture has no rows"); >+ depth.loadValue().copyFrom(EPtr.box(tex.length), 1); >+ height.loadValue().copyFrom(EPtr.box(tex[0].length), 1); >+ width.loadValue().copyFrom(EPtr.box(tex[0][0].length), 1); >+ } >+ }); >+ this._map.set( >+ `native ${type} Load(RWTexture3D<${type}>,int3 location)`, >+ func => { >+ func.implementation = function ([texture, location]) { >+ return EPtr.box(textureLoad(texture.loadValue(), [location.get(0), location.get(1), location.get(2)])); >+ } >+ }); >+ this._map.set( >+ `native void Store(RWTexture3D<${type}>,${type},uint3 location)`, >+ func => { >+ func.implementation = function ([texture, value, location]) { >+ textureStore(texture.loadValue(), value.loadValue(), [location.get(0), location.get(1), location.get(2)]); >+ } >+ }); >+ >+ function boxVector(a) >+ { >+ let result = new EPtr(new EBuffer(a.length), 0); >+ for (let i = 0; i < a.length; ++i) >+ result.set(i, a[i]); >+ return result; >+ } >+ >+ for (let length of [2, 3, 4]) { >+ } >+ } > } > > add(thing) >diff --git a/Tools/WebGPUShadingLanguageRI/SPIRV.html b/Tools/WebGPUShadingLanguageRI/SPIRV.html >index 78d008f835f9e9c234ef2df6d6deea3f7426ce65..ddc65e367dd999ddb17d29cf6c5c6e62541d2a71 100644 >--- a/Tools/WebGPUShadingLanguageRI/SPIRV.html >+++ b/Tools/WebGPUShadingLanguageRI/SPIRV.html >@@ -133,6 +133,7 @@ td { > <script src="SynthesizeCopyConstructorOperator.js"></script> > <script src="SynthesizeDefaultConstructorOperator.js"></script> > <script src="TernaryExpression.js"></script> >+ <script src="TextureOperations.js"></script> > <script src="TrapStatement.js"></script> > <script src="TypeDef.js"></script> > <script src="TypeDefResolver.js"></script> >diff --git a/Tools/WebGPUShadingLanguageRI/StandardLibrary.js b/Tools/WebGPUShadingLanguageRI/StandardLibrary.js >index 6a33236617a431bd8239baa469d3ed80c1a9a02f..6ac3eebf019ded47c147ae1f3e26a86914faab6c 100644 >--- a/Tools/WebGPUShadingLanguageRI/StandardLibrary.js >+++ b/Tools/WebGPUShadingLanguageRI/StandardLibrary.js >@@ -1897,9 +1897,10 @@ let standardLibrary = (function() { > print(`native void InterlockedCompareExchange(thread atomic_${type}*, ${type}, ${type}, thread ${type}*);`); > } > print(); >- >+ */ >+ > for (var type of [`uchar`, `ushort`, `uint`, `char`, `short`, `int`, `half`, `float`]) { >- for (var length of [``, `2`, `3`, `4`]) { >+ for (var length of [``/*, `2`, `3`, `4`*/]) { > print(`native ${type}${length} Sample(Texture1D<${type}${length}>, sampler, float location);`); > print(`native ${type}${length} Sample(Texture1D<${type}${length}>, sampler, float location, int offset);`); > print(`native ${type}${length} Load(Texture1D<${type}${length}>, int2 location);`); >@@ -2010,7 +2011,8 @@ let standardLibrary = (function() { > print(); > } > } >- >+ >+ /* > for (var type of [`half`, `float`]) { > print(`native ${type} Sample(TextureDepth2D<${type}>, sampler, float2 location);`); > print(`native ${type} Sample(TextureDepth2D<${type}>, sampler, float2 location, int2 offset);`); >diff --git a/Tools/WebGPUShadingLanguageRI/Test.html b/Tools/WebGPUShadingLanguageRI/Test.html >index 607a6953253da727b1de37678ec388b4fa240405..0de791cbd369d407fcf269d0f0d3096c5a7689e6 100644 >--- a/Tools/WebGPUShadingLanguageRI/Test.html >+++ b/Tools/WebGPUShadingLanguageRI/Test.html >@@ -127,6 +127,7 @@ > <script src="SynthesizeCopyConstructorOperator.js"></script> > <script src="SynthesizeDefaultConstructorOperator.js"></script> > <script src="TernaryExpression.js"></script> >+<script src="TextureOperations.js"></script> > <script src="TrapStatement.js"></script> > <script src="TypeDef.js"></script> > <script src="TypeDefResolver.js"></script> >diff --git a/Tools/WebGPUShadingLanguageRI/Test.js b/Tools/WebGPUShadingLanguageRI/Test.js >index ab96bc477f7f1e29dbdf62f5260ce49e5e7100d8..8659eaef951cf309c4ab86427402737cd38a3c21 100644 >--- a/Tools/WebGPUShadingLanguageRI/Test.js >+++ b/Tools/WebGPUShadingLanguageRI/Test.js >@@ -94,6 +94,123 @@ function makeEnum(program, enumName, value) > return TypedValue.box(enumType, enumMember.value.unifyNode.valueForSelectedType); > } > >+function makeSampler(program, samplerData) >+{ >+ // enum AddressMode { >+ // "clampToEdge", >+ // "repeat", >+ // "mirrorRepeat", >+ // "clampToBorderColor" >+ // } >+ // >+ // enum Filter { >+ // "nearest", >+ // "linear" >+ // } >+ // >+ // enum CompareFunction { >+ // "never", >+ // "less", >+ // "equal", >+ // "lessEqual", >+ // "greater", >+ // "notEqual", >+ // "greaterEqual", >+ // "always" >+ // } >+ // >+ // enum BorderColor { >+ // "transparentBlack", >+ // "opaqueBlack", >+ // "opaqueWhite" >+ // } >+ // >+ // dictionary SamplerData { >+ // AddressMode rAddressMode = "clampToEdge", >+ // AddressMode sAddressMode = "clampToEdge", >+ // AddressMode tAddressMode = "clampToEdge", >+ // Filter minFilter = "nearest", >+ // Filter magFilter = "nearest", >+ // Filter mipFilter = "nearest", >+ // float lodMinClamp = 0, >+ // float lodMaxClamp = FLT_MAX, >+ // unsigned long maxAnisotropy = 1, >+ // boolean normalizedCoordinates = true, >+ // CompareFunction compareFunction = "never", >+ // BorderColor borderColor = "transparentBlack" >+ // } >+ // >+ return TypedValue.box(program.intrinsics.sampler, samplerData); >+} >+ >+// Elements may either be a number or a vector of 2-4 numbers. >+// 1D Texture: An array of mipmaps. The first mipmap is the full size, and is a power-of-two. Each mipmap is half-size of the previous size. >+// 1D Texture Array: An array of 1D textures >+// 2D Texture: An array of mipmaps. The first mipmap is a rectangular array of rows, and each row is an array of elements. Both the row and column counts must be powers of two. Each mipmap is half-width and half-height of the previous size. >+// 2D Texture Array: An array of 2D textures >+// 3D Texture: An array of mipmaps. The first mipmap is a rectangular array of columns, each column is an array of rows, and each row is an array of elements. Both depth, row, and column counts must be powers of two. Each mipmap is half-depth, half-height, and half-width of the previous size. >+// Texture Cube: An array of 6 2D textures. >+// RW 1D Texture: An array of elements. The width must be a power-of-two. >+// RW 1D Texture Array: An array of RW 1D textures >+// RW 2D Texture: A rectangular array of rows, and each row is an array of elements. Both the row and column counts must be powers of two. >+// RW 2D Texture Array: An array of RW 2D textures >+// RW 3D Texture: A rectangular array of columns, each column is an array of rows, and each row is an array of elements. Both depth, row, and column counts must be powers of two. >+ >+function make1DTexture(program, mipmaps, elementType) >+{ >+ return TypedValue.box(program.intrinsics[`Texture1D<${elementType}>`], mipmaps); >+} >+ >+function make1DTextureArray(program, array, elementType) >+{ >+ return TypedValue.box(program.intrinsics[`Texture1DArray<${elementType}>`], array); >+} >+ >+function make2DTexture(program, mipmaps, elementType) >+{ >+ return TypedValue.box(program.intrinsics[`Texture2D<${elementType}>`], mipmaps); >+} >+ >+function make2DTextureArray(program, array, elementType) >+{ >+ return TypedValue.box(program.intrinsics[`Texture2DArray<${elementType}>`], array); >+} >+ >+function make3DTexture(program, mipmaps, elementType) >+{ >+ return TypedValue.box(program.intrinsics[`Texture3D<${elementType}>`], mipmaps); >+} >+ >+function makeTextureCube(program, array, elementType) >+{ >+ return TypedValue.box(program.intrinsics[`TextureCube<${elementType}>`], array); >+} >+ >+function makeRW1DTexture(program, elements, elementType) >+{ >+ return TypedValue.box(program.intrinsics[`RWTexture1D<${elementType}>`], elements); >+} >+ >+function makeRW1DTextureArray(program, array, elementType) >+{ >+ return TypedValue.box(program.intrinsics[`RWTexture1DArray<${elementType}>`], array); >+} >+ >+function makeRW2DTexture(program, rows, elementType) >+{ >+ return TypedValue.box(program.intrinsics[`RWTexture2D<${elementType}>`], rows); >+} >+ >+function makeRW2DTextureArray(program, array, elementType) >+{ >+ return TypedValue.box(program.intrinsics[`RWTexture2DArray<${elementType}>`], array); >+} >+ >+function makeRW3DTexture(program, depth, elementType) >+{ >+ return TypedValue.box(program.intrinsics[`RWTexture3D<${elementType}>`], depth); >+} >+ > function checkNumber(program, result, expected) > { > if (!result.type.unifyNode.isNumber) >@@ -5451,6 +5568,35 @@ tests.halfSimpleMath = function() { > checkHalf(program, callFunction(program, "foo", [makeHalf(program, 7), makeHalf(program, -2)]), -3.5); > } > >+tests.textureDimensions = function() { >+ let program = doPrep(` >+ uint foo(Texture1D<float> texture) { >+ uint width; >+ uint numberOfLevels; >+ GetDimensions(texture, 0, &width, &numberOfLevels); >+ return width; >+ } >+ uint bar(Texture1D<float> texture) { >+ uint width; >+ uint numberOfLevels; >+ GetDimensions(texture, 0, &width, &numberOfLevels); >+ return numberOfLevels; >+ } >+ `); >+ checkUint(program, callFunction(program, "foo", [make1DTexture(program, [[1, 7, 14, 79], [13, 16], [15]], "float")]), 4); >+ checkUint(program, callFunction(program, "bar", [make1DTexture(program, [[1, 7, 14, 79], [13, 16], [15]], "float")]), 3); >+} >+ >+tests.textureLoad = function() { >+ let program = doPrep(` >+ float foo(Texture1D<float> texture, int mipmap, int location) { >+ return Load(texture, int2(mipmap, location)); >+ } >+ `); >+ checkFloat(program, callFunction(program, "foo", [make1DTexture(program, [[1, 7, 14, 79], [13, 16], [15]], "float"), makeInt(program, 0), makeInt(program, 1)]), 7); >+ checkFloat(program, callFunction(program, "foo", [make1DTexture(program, [[1, 7, 14, 79], [13, 16], [15]], "float"), makeInt(program, 1), makeInt(program, 1)]), 16); >+} >+ > okToTest = true; > > let testFilter = /.*/; // run everything by default >diff --git a/Tools/WebGPUShadingLanguageRI/TextureOperations.js b/Tools/WebGPUShadingLanguageRI/TextureOperations.js >new file mode 100644 >index 0000000000000000000000000000000000000000..babac4b6db690a66fe9974e88ed989534a9201b9 >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/TextureOperations.js >@@ -0,0 +1,50 @@ >+/* >+ * Copyright (C) 2018 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+"use strict"; >+ >+function textureLoad(texture, path) >+{ >+ for (var index of path) { >+ if (index < 0 || index >= texture.length) >+ throw new WTrapError("[Load]", "Texture read out of bounds"); >+ texture = texture[index]; >+ } >+ return texture; >+} >+ >+function textureStore(texture, value, path) >+{ >+ do { >+ if (path.length == 0) >+ throw new Error("Zero-length store path"); >+ if (path.length == 1) { >+ texture[path[0]] = value; >+ return; >+ } else { >+ texture = texture[path[0]]; >+ path.shift(); >+ } >+ } while (true); >+} >diff --git a/Tools/WebGPUShadingLanguageRI/index.html b/Tools/WebGPUShadingLanguageRI/index.html >index 65a86411b3e770b557b41acc7e414def42403013..8366bb18d170e93f800df5822fa5eafeb43bed83 100644 >--- a/Tools/WebGPUShadingLanguageRI/index.html >+++ b/Tools/WebGPUShadingLanguageRI/index.html >@@ -127,6 +127,7 @@ > <script src="SynthesizeCopyConstructorOperator.js"></script> > <script src="SynthesizeDefaultConstructorOperator.js"></script> > <script src="TernaryExpression.js"></script> >+<script src="TextureOperations.js"></script> > <script src="TrapStatement.js"></script> > <script src="TypeDef.js"></script> > <script src="TypeDefResolver.js"></script>
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 188940
:
348066
|
348347
|
348365
|
348376
|
348433
|
348459
|
348464
|
348467
|
348521
|
348581
|
348582
|
348607
|
348661
|
348687
|
348695
|
348698
|
348705
|
348717
|
348718
|
348723
|
348724
|
348726
|
348727
|
348752
|
348758
|
348775
|
348791
|
348797
|
348798
|
348800
|
348801
|
348804