WebKit Bugzilla
Attachment 348687 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-20180831172210.patch (text/plain), 163.98 KB, created by
Myles C. Maxfield
on 2018-08-31 17:22:11 PDT
(
hide
)
Description:
WIP
Filename:
MIME Type:
Creator:
Myles C. Maxfield
Created:
2018-08-31 17:22:11 PDT
Size:
163.98 KB
patch
obsolete
>Subversion Revision: 235569 >diff --git a/Tools/ChangeLog b/Tools/ChangeLog >index 7a499fd5f42edb18d476bbb3b429090750209c11..99f2933a029f5cd7fa0ce8a2b0e5f5b1cc7a0fa2 100644 >--- a/Tools/ChangeLog >+++ b/Tools/ChangeLog >@@ -1,3 +1,142 @@ >+2018-08-31 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.checkFalse): >+ (Intrinsics): >+ * WebGPUShadingLanguageRI/NameResolver.js: >+ (NameResolver.prototype._handlePropertyAccess): >+ (NameResolver.prototype.visitDotExpression): >+ (NameResolver.prototype.visitIndexExpression): >+ * 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/Texture.js: Added. >+ (Texture): >+ (Texture.prototype.get dimension): >+ (Texture.prototype.get width): >+ (Texture.prototype.get height): >+ (Texture.prototype.get depth): >+ (Texture.prototype.get levelCount): >+ (Texture.prototype.get layerCount): >+ (Texture.prototype.get innerType): >+ (Texture.prototype.get data): >+ (Texture.prototype.elementChecked): >+ (Texture.prototype.setElementChecked): >+ (Texture1D): >+ (Texture1D.prototype.widthAtLevel): >+ (Texture1D.prototype.heightAtLevel): >+ (Texture1D.prototype.depthAtLevel): >+ (Texture1D.prototype.element): >+ (Texture1D.prototype.setElement): >+ (Texture1DArray): >+ (Texture1DArray.prototype.widthAtLevel): >+ (Texture1DArray.prototype.heightAtLevel): >+ (Texture1DArray.prototype.depthAtLevel): >+ (Texture1DArray.prototype.element): >+ (Texture1DArray.prototype.setElement): >+ (Texture2D): >+ (Texture2D.prototype.widthAtLevel): >+ (Texture2D.prototype.heightAtLevel): >+ (Texture2D.prototype.depthAtLevel): >+ (Texture2D.prototype.element): >+ (Texture2D.prototype.setElement): >+ (Texture2DArray): >+ (Texture2DArray.prototype.widthAtLevel): >+ (Texture2DArray.prototype.heightAtLevel): >+ (Texture2DArray.prototype.depthAtLevel): >+ (Texture2DArray.prototype.element): >+ (Texture2DArray.prototype.setElement): >+ (Texture3D): >+ (Texture3D.prototype.widthAtLevel): >+ (Texture3D.prototype.heightAtLevel): >+ (Texture3D.prototype.depthAtLevel): >+ (Texture3D.prototype.element): >+ (Texture3D.prototype.setElement): >+ (TextureCube): >+ (TextureCube.prototype.widthAtLevel): >+ (TextureCube.prototype.heightAtLevel): >+ (TextureCube.prototype.depthAtLevel): >+ (TextureCube.prototype.element): >+ (TextureCube.prototype.setElement): >+ (Texture1DRW): >+ (Texture1DRW.prototype.widthAtLevel): >+ (Texture1DRW.prototype.heightAtLevel): >+ (Texture1DRW.prototype.depthAtLevel): >+ (Texture1DRW.prototype.element): >+ (Texture1DRW.prototype.setElement): >+ (Texture1DArrayRW): >+ (Texture1DArrayRW.prototype.widthAtLevel): >+ (Texture1DArrayRW.prototype.heightAtLevel): >+ (Texture1DArrayRW.prototype.depthAtLevel): >+ (Texture1DArrayRW.prototype.element): >+ (Texture1DArrayRW.prototype.setElement): >+ (Texture2DRW): >+ (Texture2DRW.prototype.widthAtLevel): >+ (Texture2DRW.prototype.heightAtLevel): >+ (Texture2DRW.prototype.depthAtLevel): >+ (Texture2DRW.prototype.element): >+ (Texture2DRW.prototype.setElement): >+ (Texture2DArrayRW): >+ (Texture2DArrayRW.prototype.widthAtLevel): >+ (Texture2DArrayRW.prototype.heightAtLevel): >+ (Texture2DArrayRW.prototype.depthAtLevel): >+ (Texture2DArrayRW.prototype.element): >+ (Texture2DArrayRW.prototype.setElement): >+ (Texture3DRW): >+ (Texture3DRW.prototype.widthAtLevel): >+ (Texture3DRW.prototype.heightAtLevel): >+ (Texture3DRW.prototype.depthAtLevel): >+ (Texture3DRW.prototype.element): >+ (Texture3DRW.prototype.setElement): >+ * WebGPUShadingLanguageRI/TextureOperations.js: Added. >+ (depthCompareOperation): >+ (conversionToRGBA): >+ (implicitDerivative): >+ (projectionOperation): >+ (cubeMapFaceSelection): >+ (cubeMapCoordinateTransformation): >+ (cubeMapDerivativeTransformation): >+ (scaleFactorOperation): >+ (levelOfDetailOperation): >+ (nearest): >+ (imageLevelSelection): >+ (strqaToUVWATransformation): >+ (rne): >+ (uvwaToIJKLNTransformationAndArrayLayerSelection): >+ (integerTexelCoordinateOperations): >+ (mirror): >+ (transform): >+ (wrappingOperation): >+ (texelGathering): >+ (computeTau.reduce): >+ (computeTau.shouldBeBorder): >+ (computeTau.accessColor): >+ (computeTau): >+ (texelFiltering): >+ (sampleTexture): >+ * WebGPUShadingLanguageRI/index.html: >+ > 2018-08-31 Myles C. Maxfield <mmaxfield@apple.com> > > [WHLSL] Remove useless code in NameResolver >diff --git a/Tools/WebGPUShadingLanguageRI/All.js b/Tools/WebGPUShadingLanguageRI/All.js >index 9c2a37150c1e976b926cfbee23437520a8de4a47..00fe5d011bb0c4b5d3546c5d20a8bcd0a32d363c 100644 >--- a/Tools/WebGPUShadingLanguageRI/All.js >+++ b/Tools/WebGPUShadingLanguageRI/All.js >@@ -150,6 +150,8 @@ load("SynthesizeStructAccessors.js"); > load("SynthesizeCopyConstructorOperator.js"); > load("SynthesizeDefaultConstructorOperator.js"); > load("TernaryExpression.js"); >+load("Texture.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 b004067f5ebfb3a8b4bd98e437a8c0768be26f1e..b571a4eaf6b114b5e5875f0bf5f7a9eab437497f 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,787 @@ class Intrinsics { > > for (let setter of BuiltinMatrixSetter.functions()) > this._map.set(setter.toString(), func => setter.instantiateImplementation(func)); >+ >+ function checkUndefined(origin, explanation, value) >+ { >+ if (value == undefined) >+ throw new WTrapError("[Load]", "Texture read out of bounds"); >+ return value; >+ } >+ >+ function checkFalse(origin, explanation, value) >+ { >+ if (value == false) >+ throw new WTrapError("[Store]", "Texture store out of bounds"); >+ } >+ >+ for (let type of ["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]) { >+ let locationArray = [location.loadValue(), 0, 0, 1, 0]; >+ return EPtr.box(sampleTexture(texture.loadValue(), sampler.loadValue(), locationArray, undefined, undefined, undefined, undefined, undefined, undefined)); >+ } >+ }); >+ this._map.set( >+ `native ${type} Sample(Texture1D<${type}>,sampler,float location,int offset)`, >+ func => { >+ func.implementation = function([texture, sampler, location, offset]) { >+ let locationArray = [location.loadValue(), 0, 0, 1, 0]; >+ let deltaArray = [offset.loadValue(), 0, 0]; >+ return EPtr.box(sampleTexture(texture.loadValue(), sampler.loadValue(), locationArray, deltaArray, undefined, undefined, undefined, undefined, undefined)); >+ } >+ }); >+ this._map.set( >+ `native ${type} Load(Texture1D<${type}>,int2 location)`, >+ func => { >+ func.implementation = function ([texture, location]) { >+ return EPtr.box(checkUndefined("[Load]", "Texture read out of bounds", texture.loadValue().elementChecked(0, location.get(1), 0, 0, location.get(0)))); >+ } >+ }); >+ this._map.set( >+ `native ${type} Load(Texture1D<${type}>,int2 location,int offset)`, >+ func => { >+ func.implementation = function ([texture, location, offset]) { >+ return EPtr.box(checkUndefined("[Load]", "Texture read out of bounds", texture.loadValue().elementChecked(0, location.get(1), 0, 0, location.get(0) + 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.levelCount) >+ throw new WTrapError("[load]", "Reading from nonexistant mip level of texture"); >+ width.loadValue().copyFrom(EPtr.box(tex.widthAtLevel(mipID)), 1); >+ numberOfLevels.loadValue().copyFrom(EPtr.box(tex.levelCount), 1); >+ } >+ }); >+ >+ this._map.set( >+ `native ${type} Sample(Texture1DArray<${type}>,sampler,float2 location)`, >+ func => { >+ func.implementation = function([texture, sampler, location]) { >+ let locationArray = [location.get(0), 0, 0, 1, location.get(1)]; >+ return EPtr.box(sampleTexture(texture.loadValue(), sampler.loadValue(), locationArray, undefined, undefined, undefined, undefined, undefined, undefined)); >+ } >+ }); >+ this._map.set( >+ `native ${type} Sample(Texture1DArray<${type}>,sampler,float2 location,int offset)`, >+ func => { >+ func.implementation = function([texture, sampler, location, offset]) { >+ let locationArray = [location.get(0), 0, 0, 1, location.get(1)]; >+ let deltaArray = [offset.loadValue(), 0, 0]; >+ return EPtr.box(sampleTexture(texture.loadValue(), sampler.loadValue(), locationArray, deltaArray, undefined, undefined, undefined, undefined, undefined)); >+ } >+ }); >+ this._map.set( >+ `native ${type} Load(Texture1DArray<${type}>,int3 location)`, >+ func => { >+ func.implementation = function ([texture, location]) { >+ return EPtr.box(checkUndefined("[Load]", "Texture read out of bounds", texture.loadValue().elementChecked(location.get(2), location.get(1), 0, 0, location.get(0)))); >+ } >+ }); >+ this._map.set( >+ `native ${type} Load(Texture1DArray<${type}>,int3 location,int offset)`, >+ func => { >+ func.implementation = function ([texture, location, offset]) { >+ return EPtr.box(checkUndefined("[Load]", "Texture read out of bounds", texture.loadValue().elementChecked(location.get(2), location.get(1), 0, 0, location.get(0) + 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 (mipID >= tex.levelCount) >+ throw new WTrapError("[load]", "Reading from nonexistant mip level of texture"); >+ width.loadValue().copyFrom(EPtr.box(tex.widthAtLevel(mipID)), 1); >+ elements.loadValue().copyFrom(EPtr.box(tex.layerCount), 1); >+ numberOfLevels.loadValue().copyFrom(EPtr.box(tex.levelCount), 1); >+ } >+ }); >+ >+ this._map.set( >+ `native ${type} Sample(Texture2D<${type}>,sampler,float2 location)`, >+ func => { >+ func.implementation = function([texture, sampler, location]) { >+ let locationArray = [location.get(0), location.get(1), 0, 1, 0]; >+ return EPtr.box(sampleTexture(texture.loadValue(), sampler.loadValue(), locationArray, undefined, undefined, undefined, undefined, undefined, undefined)); >+ } >+ }); >+ this._map.set( >+ `native ${type} Sample(Texture2D<${type}>,sampler,float2 location,int2 offset)`, >+ func => { >+ func.implementation = function([texture, sampler, location, offset]) { >+ let locationArray = [location.get(0), location.get(1), 0, 1, 0]; >+ let deltaArray = [offset.get(0), offset.get(1), 0]; >+ return EPtr.box(sampleTexture(texture.loadValue(), sampler.loadValue(), locationArray, deltaArray, undefined, undefined, undefined, undefined, undefined)); >+ } >+ }); >+ this._map.set( >+ `native ${type} SampleBias(Texture2D<${type}>,sampler,float2 location,float Bias)`, >+ func => { >+ func.implementation = function([texture, sampler, location, bias]) { >+ let locationArray = [location.get(0), location.get(1), 0, 1, 0]; >+ return EPtr.box(sampleTexture(texture.loadValue(), sampler.loadValue(), locationArray, undefined, bias.loadValue(), undefined, undefined, undefined, undefined)); >+ } >+ }); >+ this._map.set( >+ `native ${type} SampleBias(Texture2D<${type}>,sampler,float2 location,float Bias,int2 offset)`, >+ func => { >+ func.implementation = function([texture, sampler, location, bias, offset]) { >+ let locationArray = [location.get(0), location.get(1), 0, 1, 0]; >+ let deltaArray = [offset.get(0), offset.get(1), 0]; >+ return EPtr.box(sampleTexture(texture.loadValue(), sampler.loadValue(), locationArray, deltaArray, bias.loadValue(), undefined, undefined, undefined, undefined)); >+ } >+ }); >+ this._map.set( >+ `native ${type} SampleGrad(Texture2D<${type}>,sampler,float2 location,float2 DDX,float2 DDY)`, >+ func => { >+ func.implementation = function([texture, sampler, location, ddx, ddy]) { >+ let locationArray = [location.get(0), location.get(1), 0, 1, 0]; >+ let ddxArray = [ddx.get(0), ddx.get(1), 0]; >+ let ddyArray = [ddy.get(0), ddy.get(1), 0]; >+ return EPtr.box(sampleTexture(texture.loadValue(), sampler.loadValue(), locationArray, undefined, undefined, ddxArray, ddyArray, undefined, undefined)); >+ } >+ }); >+ 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]) { >+ let locationArray = [location.get(0), location.get(1), 0, 1, 0]; >+ let ddxArray = [ddx.get(0), ddx.get(1), 0]; >+ let ddyArray = [ddy.get(0), ddy.get(1), 0]; >+ let deltaArray = [offset.get(0), offset.get(1), 0]; >+ return EPtr.box(sampleTexture(texture.loadValue(), sampler.loadValue(), locationArray, deltaArray, undefined, ddxArray, ddyArray, undefined, undefined)); >+ } >+ }); >+ this._map.set( >+ `native ${type} SampleLevel(Texture2D<${type}>,sampler,float2 location,float LOD)`, >+ func => { >+ func.implementation = function([texture, sampler, location, lod]) { >+ let locationArray = [location.get(0), location.get(1), 0, 1, 0]; >+ return EPtr.box(sampleTexture(texture.loadValue(), sampler.loadValue(), locationArray, undefined, undefined, undefined, undefined, lod.loadValue(), undefined)); >+ } >+ }); >+ this._map.set( >+ `native ${type} SampleLevel(Texture2D<${type}>,sampler,float2 location,float LOD,int2 offset)`, >+ func => { >+ func.implementation = function([texture, sampler, location, lod, offset]) { >+ let locationArray = [location.get(0), location.get(1), 0, 1, 0]; >+ let deltaArray = [offset.get(0), offset.get(1), 0]; >+ return EPtr.box(sampleTexture(texture.loadValue(), sampler.loadValue(), locationArray, deltaArray, undefined, undefined, undefined, lod.loadValue(), undefined)); >+ } >+ }); >+ 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(checkUndefined("[Load]", "Texture read out of bounds", texture.loadValue().elementChecked(0, location.get(2), 0, location.get(1), location.get(0)))); >+ } >+ }); >+ this._map.set( >+ `native ${type} Load(Texture2D<${type}>,int3 location,int2 offset)`, >+ func => { >+ func.implementation = function ([texture, location, offset]) { >+ return EPtr.box(checkUndefined("[Load]", "Texture read out of bounds", texture.loadValue().elementChecked(0, location.get(2), 0, location.get(1) + offset.get(1), location.get(0) + offset.get(0)))); >+ } >+ }); >+ 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.levelCount) >+ throw new WTrapError("[load]", "Reading from nonexistant mip level of texture"); >+ height.loadValue().copyFrom(EPtr.box(tex.heightAtLevel(mipID)), 1); >+ width.loadValue().copyFrom(EPtr.box(tex.widthAtLevel(mipID)), 1); >+ numberOfLevels.loadValue().copyFrom(EPtr.box(tex.levelCount), 1); >+ } >+ }); >+ >+ this._map.set( >+ `native ${type} Sample(Texture2DArray<${type}>,sampler,float3 location)`, >+ func => { >+ func.implementation = function([texture, sampler, location]) { >+ let locationArray = [location.get(0), location.get(1), 0, 1, location.get(2)]; >+ return EPtr.box(sampleTexture(texture.loadValue(), sampler.loadValue(), locationArray, undefined, undefined, undefined, undefined, undefined, undefined)); >+ } >+ }); >+ this._map.set( >+ `native ${type} Sample(Texture2DArray<${type}>,sampler,float3 location,int2 offset)`, >+ func => { >+ func.implementation = function([texture, sampler, location, offset]) { >+ let locationArray = [location.get(0), location.get(1), 0, 1, location.get(2)]; >+ let deltaArray = [offset.get(0), offset.get(1), 0]; >+ return EPtr.box(sampleTexture(texture.loadValue(), sampler.loadValue(), locationArray, deltaArray, undefined, undefined, undefined, undefined, undefined)); >+ } >+ }); >+ this._map.set( >+ `native ${type} SampleBias(Texture2DArray<${type}>,sampler,float3 location,float Bias)`, >+ func => { >+ func.implementation = function([texture, sampler, location, bias]) { >+ let locationArray = [location.get(0), location.get(1), 0, 1, location.get(2)]; >+ return EPtr.box(sampleTexture(texture.loadValue(), sampler.loadValue(), locationArray, undefined, bias.loadValue(), undefined, undefined, undefined, undefined)); >+ } >+ }); >+ this._map.set( >+ `native ${type} SampleBias(Texture2DArray<${type}>,sampler,float3 location,float Bias,int2 offset)`, >+ func => { >+ func.implementation = function([texture, sampler, location, bias, offset]) { >+ let locationArray = [location.get(0), location.get(1), 0, 1, location.get(2)]; >+ let deltaArray = [offset.get(0), offset.get(1), 0]; >+ return EPtr.box(sampleTexture(texture.loadValue(), sampler.loadValue(), locationArray, deltaArray, bias.loadValue(), undefined, undefined, undefined, undefined)); >+ } >+ }); >+ this._map.set( >+ `native ${type} SampleGrad(Texture2DArray<${type}>,sampler,float3 location,float2 DDX,float2 DDY)`, >+ func => { >+ func.implementation = function([texture, sampler, location, ddx, ddy]) { >+ let locationArray = [location.get(0), location.get(1), 0, 1, location.get(2)]; >+ let ddxArray = [ddx.get(0), ddx.get(1), 0]; >+ let ddyArray = [ddy.get(0), ddy.get(1), 0]; >+ return EPtr.box(sampleTexture(texture.loadValue(), sampler.loadValue(), locationArray, undefined, undefined, ddxArray, ddyArray, undefined, undefined)); >+ } >+ }); >+ 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]) { >+ let locationArray = [location.get(0), location.get(1), 0, 1, location.get(2)]; >+ let ddxArray = [ddx.get(0), ddx.get(1), 0]; >+ let ddyArray = [ddy.get(0), ddy.get(1), 0]; >+ let deltaArray = [offset.get(0), offset.get(1), 0]; >+ return EPtr.box(sampleTexture(texture.loadValue(), sampler.loadValue(), locationArray, deltaArray, undefined, ddxArray, ddyArray, undefined, undefined)); >+ } >+ }); >+ this._map.set( >+ `native ${type} SampleLevel(Texture2DArray<${type}>,sampler,float3 location,float LOD)`, >+ func => { >+ func.implementation = function([texture, sampler, location, lod]) { >+ let locationArray = [location.get(0), location.get(1), 0, 1, location.get(2)]; >+ return EPtr.box(sampleTexture(texture.loadValue(), sampler.loadValue(), locationArray, undefined, undefined, undefined, undefined, lod.loadValue(), undefined)); >+ } >+ }); >+ this._map.set( >+ `native ${type} SampleLevel(Texture2DArray<${type}>,sampler,float3 location,float LOD,int2 offset)`, >+ func => { >+ func.implementation = function([texture, sampler, location, lod, offset]) { >+ let locationArray = [location.get(0), location.get(1), 0, 1, location.get(2)]; >+ let deltaArray = [offset.get(0), offset.get(1), 0]; >+ return EPtr.box(sampleTexture(texture.loadValue(), sampler.loadValue(), locationArray, deltaArray, undefined, undefined, undefined, lod.loadValue(), undefined)); >+ } >+ }); >+ 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(checkUndefined("[Load]", "Texture read out of bounds", texture.loadValue().elementChecked(location.get(3), location.get(2), 0, location.get(1), location.get(0)))); >+ } >+ }); >+ this._map.set( >+ `native ${type} Load(Texture2DArray<${type}>,int4 location,int2 offset)`, >+ func => { >+ func.implementation = function ([texture, location, offset]) { >+ return EPtr.box(checkUndefined("[Load]", "Texture read out of bounds", texture.loadValue().elementChecked(location.get(3), location.get(2), 0, location.get(1) + offset.get(1), location.get(0) + offset.get(0)))); >+ } >+ }); >+ 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 (mipID >= tex.levelCount) >+ throw new WTrapError("[load]", "Reading from nonexistant mip level of texture"); >+ height.loadValue().copyFrom(EPtr.box(tex.heightAtLevel(mipID)), 1); >+ width.loadValue().copyFrom(EPtr.box(tex.widthAtLevel(mipID)), 1); >+ elements.loadValue().copyFrom(EPtr.box(tex.layerCount), 1); >+ numberOfLevels.loadValue().copyFrom(EPtr.box(tex.levelCount), 1); >+ } >+ }); >+ >+ this._map.set( >+ `native ${type} Sample(Texture3D<${type}>,sampler,float3 location)`, >+ func => { >+ func.implementation = function([texture, sampler, location]) { >+ let locationArray = [location.get(0), location.get(1), location.get(2), 1, 0]; >+ return EPtr.box(sampleTexture(texture.loadValue(), sampler.loadValue(), locationArray, undefined, undefined, undefined, undefined, undefined, undefined)); >+ } >+ }); >+ this._map.set( >+ `native ${type} Sample(Texture3D<${type}>,sampler,float3 location,int3 offset)`, >+ func => { >+ func.implementation = function([texture, sampler, location, offset]) { >+ let locationArray = [location.get(0), location.get(1), location.get(2), 1, 0]; >+ let deltaArray = [offset.get(0), offset.get(1), offset.get(2)]; >+ return EPtr.box(sampleTexture(texture.loadValue(), sampler.loadValue(), locationArray, deltaArray, undefined, undefined, undefined, undefined, undefined)); >+ } >+ }); >+ 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(checkUndefined("[Load]", "Texture read out of bounds", texture.loadValue().elementChecked(0, location.get(3), location.get(2), location.get(1), location.get(0)))); >+ } >+ }); >+ this._map.set( >+ `native ${type} Load(Texture3D<${type}>,int4 location,int3 offset)`, >+ func => { >+ func.implementation = function ([texture, location, offset]) { >+ return EPtr.box(checkUndefined("[Load]", "Texture read out of bounds", texture.loadValue().elementChecked(0, location.get(3), location.get(2) + offset.get(2), location.get(1) + offset.get(1), location.get(0) + offset.get(0)))); >+ } >+ }); >+ 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.levelCount) >+ throw new WTrapError("[load]", "Reading from nonexistant mip level of texture"); >+ depth.loadValue().copyFrom(EPtr.box(tex.depthAtLevel(mipID)), 1); >+ height.loadValue().copyFrom(EPtr.box(tex.heightAtLevel(mipID)), 1); >+ width.loadValue().copyFrom(EPtr.box(tex.widthAtLevel(mipID)), 1); >+ numberOfLevels.loadValue().copyFrom(EPtr.box(tex.levelCount), 1); >+ } >+ }); >+ >+ this._map.set( >+ `native ${type} Sample(TextureCube<${type}>,sampler,float3 location)`, >+ func => { >+ func.implementation = function([texture, sampler, location]) { >+ // FIXME: Implement cubemap sampling >+ } >+ }); >+ this._map.set( >+ `native ${type} SampleBias(TextureCube<${type}>,sampler,float3 location,float Bias)`, >+ func => { >+ func.implementation = function([texture, sampler, location, bias]) { >+ // FIXME: Implement cubemap sampling >+ } >+ }); >+ this._map.set( >+ `native ${type} SampleGrad(TextureCube<${type}>,sampler,float3 location,float3 DDX,float3 DDY)`, >+ func => { >+ func.implementation = function([texture, sampler, location, ddx, ddy]) { >+ // FIXME: Implement cubemap sampling >+ } >+ }); >+ this._map.set( >+ `native ${type} SampleLevel(TextureCube<${type}>,sampler,float3 location,float LOD)`, >+ func => { >+ func.implementation = function([texture, sampler, location, lod]) { >+ // FIXME: Implement cubemap sampling >+ } >+ }); >+ 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.layerCount != 6) >+ throw new Error("Cube texture doesn't have 6 faces"); >+ if (mipID >= tex.levelCount) >+ throw new WTrapError("[load]", "Reading from nonexistant mip level of texture"); >+ height.loadValue().copyFrom(EPtr.box(tex.heightAtLevel(mipID)), 1); >+ width.loadValue().copyFrom(EPtr.box(tex.widthAtLevel(mipID)), 1); >+ numberOfLevels.loadValue().copyFrom(EPtr.box(tex.levelCount), 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().width), 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().width), 1); >+ } >+ }); >+ this._map.set( >+ `native ${type} Load(RWTexture1D<${type}>,int location)`, >+ func => { >+ func.implementation = function ([texture, location]) { >+ return EPtr.box(checkUndefined("[Load]", "Texture read out of bounds", texture.loadValue().elementChecked(0, 0, 0, 0, location.loadValue()))); >+ } >+ }); >+ this._map.set( >+ `native void Store(RWTexture1D<${type}>,${type},uint location)`, >+ func => { >+ func.implementation = function ([texture, value, location]) { >+ checkFalse("[Load]", "Texture read out of bounds", texture.loadValue().setElementChecked(0, 0, 0, 0, location.loadValue(), value.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(); >+ elements.loadValue().copyFrom(EPtr.box(tex.layerCount), 1); >+ width.loadValue().copyFrom(EPtr.box(tex.width), 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(); >+ elements.loadValue().copyFrom(EPtr.box(tex.layerCount), 1); >+ width.loadValue().copyFrom(EPtr.box(tex.width), 1); >+ } >+ }); >+ this._map.set( >+ `native ${type} Load(RWTexture1DArray<${type}>,int2 location)`, >+ func => { >+ func.implementation = function ([texture, location]) { >+ return EPtr.box(checkUndefined("[Load]", "Texture read out of bounds", texture.loadValue().elementChecked(location.get(1), 0, 0, 0, location.get(0)))); >+ } >+ }); >+ this._map.set( >+ `native void Store(RWTexture1DArray<${type}>,${type},uint2 location)`, >+ func => { >+ func.implementation = function ([texture, value, location]) { >+ checkFalse("[Load]", "Texture read out of bounds", texture.loadValue().setElementChecked(location.get(1), 0, 0, 0, location.get(0), value.loadValue())); >+ } >+ }); >+ >+ 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(); >+ height.loadValue().copyFrom(EPtr.box(tex.height), 1); >+ width.loadValue().copyFrom(EPtr.box(tex.width), 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(); >+ height.loadValue().copyFrom(EPtr.box(tex.height), 1); >+ width.loadValue().copyFrom(EPtr.box(tex.width), 1); >+ } >+ }); >+ this._map.set( >+ `native ${type} Load(RWTexture2D<${type}>,int2 location)`, >+ func => { >+ func.implementation = function ([texture, location]) { >+ return EPtr.box(checkUndefined("[Load]", "Texture read out of bounds", texture.loadValue().elementChecked(0, 0, 0, location.get(1), location.get(0)))); >+ } >+ }); >+ this._map.set( >+ `native void Store(RWTexture2D<${type}>,${type},uint2 location)`, >+ func => { >+ func.implementation = function ([texture, value, location]) { >+ checkFalse("[Load]", "Texture read out of bounds", texture.loadValue().setElementChecked(0, 0, 0, location.get(1), location.get(0), value.loadValue())); >+ } >+ }); >+ >+ 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(); >+ elements.loadValue().copyFrom(EPtr.box(tex.layerCount), 1); >+ height.loadValue().copyFrom(EPtr.box(tex.height), 1); >+ width.loadValue().copyFrom(EPtr.box(tex.width), 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(); >+ elements.loadValue().copyFrom(EPtr.box(tex.layerCount), 1); >+ height.loadValue().copyFrom(EPtr.box(tex.height), 1); >+ width.loadValue().copyFrom(EPtr.box(tex.width), 1); >+ } >+ }); >+ this._map.set( >+ `native ${type} Load(RWTexture2DArray<${type}>,int3 location)`, >+ func => { >+ func.implementation = function ([texture, location]) { >+ return EPtr.box(checkUndefined("[Load]", "Texture read out of bounds", texture.loadValue().elementChecked(location.get(2), 0, 0, location.get(1), location.get(0)))); >+ } >+ }); >+ this._map.set( >+ `native void Store(RWTexture2DArray<${type}>,${type},uint3 location)`, >+ func => { >+ func.implementation = function ([texture, value, location]) { >+ checkFalse("[Load]", "Texture read out of bounds", texture.loadValue().setElementChecked(location.get(2), 0, 0, location.get(1), location.get(0), value.loadValue())); >+ } >+ }); >+ >+ 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(); >+ depth.loadValue().copyFrom(EPtr.box(tex.depth), 1); >+ height.loadValue().copyFrom(EPtr.box(tex.height), 1); >+ width.loadValue().copyFrom(EPtr.box(tex.width), 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(); >+ depth.loadValue().copyFrom(EPtr.box(tex.depth), 1); >+ height.loadValue().copyFrom(EPtr.box(tex.height), 1); >+ width.loadValue().copyFrom(EPtr.box(tex.width), 1); >+ } >+ }); >+ this._map.set( >+ `native ${type} Load(RWTexture3D<${type}>,int3 location)`, >+ func => { >+ func.implementation = function ([texture, location]) { >+ return EPtr.box(checkUndefined("[Load]", "Texture read out of bounds", texture.loadValue().elementChecked(0, 0, location.get(2), location.get(1), location.get(0)))); >+ } >+ }); >+ this._map.set( >+ `native void Store(RWTexture3D<${type}>,${type},uint3 location)`, >+ func => { >+ func.implementation = function ([texture, value, location]) { >+ checkFalse("[Load]", "Texture read out of bounds", texture.loadValue().setElementChecked(0, 0, location.get(2), location.get(1), location.get(0), value.loadValue())); >+ } >+ }); >+ >+ 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/NameResolver.js b/Tools/WebGPUShadingLanguageRI/NameResolver.js >index a5da2ca5c1e2b9edee095f1664a2bc4b8f308284..9a099f485e6e927e16437bbf82641f61e4525cf1 100644 >--- a/Tools/WebGPUShadingLanguageRI/NameResolver.js >+++ b/Tools/WebGPUShadingLanguageRI/NameResolver.js >@@ -166,6 +166,16 @@ class NameResolver extends Visitor { > super.visitReturn(node); > } > >+ _handlePropertyAccess(node) >+ { >+ node.possibleGetOverloads = this._nameContext.get(Func, node.getFuncName); >+ node.possibleSetOverloads = this._nameContext.get(Func, node.setFuncName); >+ node.possibleAndOverloads = this._nameContext.get(Func, node.andFuncName); >+ >+ if (!node.possibleGetOverloads && !node.possibleAndOverloads) >+ throw new WTypeError(node.origin.originString, "Cannot find either " + node.getFuncName + " or " + node.andFuncName); >+ } >+ > visitDotExpression(node) > { > // This could be a reference to an enum. Let's resolve that now. >@@ -180,9 +190,16 @@ class NameResolver extends Visitor { > } > } > >+ this._handlePropertyAccess(node); > super.visitDotExpression(node); > } > >+ visitIndexExpression(node) >+ { >+ this._handlePropertyAccess(node); >+ super.visitIndexExpression(node); >+ } >+ > visitCallExpression(node) > { > let funcs = this._nameContext.get(Func, node.name); >diff --git a/Tools/WebGPUShadingLanguageRI/SPIRV.html b/Tools/WebGPUShadingLanguageRI/SPIRV.html >index 78d008f835f9e9c234ef2df6d6deea3f7426ce65..061a476414fe2b29287ee0c3d94bf027eae4f00c 100644 >--- a/Tools/WebGPUShadingLanguageRI/SPIRV.html >+++ b/Tools/WebGPUShadingLanguageRI/SPIRV.html >@@ -133,6 +133,8 @@ td { > <script src="SynthesizeCopyConstructorOperator.js"></script> > <script src="SynthesizeDefaultConstructorOperator.js"></script> > <script src="TernaryExpression.js"></script> >+ <script src="Texture.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 3dd4fee18600d5cd2a895ad5a479721da7788cc1..d8e16765794cd01309de4479d27d75e12730353f 100644 >--- a/Tools/WebGPUShadingLanguageRI/StandardLibrary.js >+++ b/Tools/WebGPUShadingLanguageRI/StandardLibrary.js >@@ -57,7 +57,7 @@ let standardLibrary = (function() { > } > print(`native typedef sampler;`); > for (var type of [`Texture1D`, `RWTexture1D`, `Texture1DArray`, `RWTexture1DArray`, `Texture2D`, `RWTexture2D`, `Texture2DArray`, `RWTexture2DArray`, `Texture3D`, `RWTexture3D`, `TextureCube`]) { >- for (var typeArgumentBase of [`bool`, `uchar`, `ushort`, `uint`, `char`, `short`, `int`, `half`, `float`]) { >+ for (var typeArgumentBase of [`uchar`, `ushort`, `uint`, `char`, `short`, `int`, `half`, `float`]) { > for (var size of [``, `2`, `3`, `4`]) { > print(`native typedef ${type}<${typeArgumentBase}${size}>;`); > } >@@ -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..20a26347f3e89ef31e7234f849bd953eee6cd889 100644 >--- a/Tools/WebGPUShadingLanguageRI/Test.html >+++ b/Tools/WebGPUShadingLanguageRI/Test.html >@@ -127,6 +127,8 @@ > <script src="SynthesizeCopyConstructorOperator.js"></script> > <script src="SynthesizeDefaultConstructorOperator.js"></script> > <script src="TernaryExpression.js"></script> >+<script src="Texture.js"></script> >+<script src="TextureOperations.js"></script> > <script src="TrapStatement.js"></script> > <script src="TypeDef.js"></script> > <script src="TypeDefResolver.js"></script> >@@ -152,7 +154,7 @@ > <script> > function doTestInBrowser() > { >- var tester = doTest(/.*/); >+ var tester = doTest(/textureStore/); > var lastTime; > function next() > { >diff --git a/Tools/WebGPUShadingLanguageRI/Test.js b/Tools/WebGPUShadingLanguageRI/Test.js >index 4a11c1858599778ff391b04f2635c5b71005df7f..6e31561ae2d95fd0e88615e465e270811978df17 100644 >--- a/Tools/WebGPUShadingLanguageRI/Test.js >+++ b/Tools/WebGPUShadingLanguageRI/Test.js >@@ -94,6 +94,144 @@ function makeEnum(program, enumName, value) > return TypedValue.box(enumType, enumMember.value.unifyNode.valueForSelectedType); > } > >+function makeSampler(program, dict) >+{ >+ // enum WebGPUAddressMode { >+ // "clampToEdge", >+ // "repeat", >+ // "mirrorRepeat", >+ // "clampToBorderColor" >+ // } >+ // >+ // enum WebGPUFilterMode { >+ // "nearest", >+ // "linear" >+ // } >+ // >+ // enum WebGPUCompareFunction { >+ // "never", >+ // "less", >+ // "equal", >+ // "lessEqual", >+ // "greater", >+ // "notEqual", >+ // "greaterEqual", >+ // "always" >+ // } >+ // >+ // enum WebGPUBorderColor { >+ // "transparentBlack", >+ // "opaqueBlack", >+ // "opaqueWhite" >+ // } >+ // >+ // dictionary WebGPUSamplerDescriptor { >+ // WebGPUddressMode rAddressMode = "clampToEdge"; >+ // WebGPUddressMode sAddressMode = "clampToEdge"; >+ // WebGPUddressMode tAddressMode = "clampToEdge"; >+ // WebGPUFilterModeEnum magFilter = "nearest"; >+ // WebGPUFilterModeEnum minFilter = "nearest"; >+ // WebGPUFilterModeEnum mipmapFilter = "nearest"; >+ // float lodMinClamp = 0; >+ // float lodMaxClamp = Number.MAX_VALUE; >+ // unsigned long maxAnisotropy = 1; >+ // WebGPUCompareFunction compareFunction = "never"; >+ // WebGPUBorderColor borderColor = "transparentBlack"; >+ // }; >+ >+ let samplerData = {}; >+ samplerData.rAddressMode = dict.rAddressMode, >+ samplerData.sAddressMode = dict.sAddressMode, >+ samplerData.tAddressMode = dict.tAddressMode, >+ samplerData.magFilter = dict.magFilter; >+ samplerData.minFilter = dict.minFilter >+ samplerData.mipmapFilter = dict.mipmapFilter; >+ samplerData.lodMinClamp = dict.lodMinClamp, >+ samplerData.lodMaxClamp = dict.lodMaxClamp, >+ samplerData.maxAnisotropy = dict.maxAnisotropy, >+ samplerData.compareFunction = dict.compareFunction; >+ samplerData.borderColor = dict.borderColor; >+ >+ if (samplerData.rAddressMode == undefined) >+ samplerData.rAddressMode = "clampToEdge"; >+ if (samplerData.sAddressMode == undefined) >+ samplerData.sAddressMode = "clampToEdge"; >+ if (samplerData.tAddressMode == undefined) >+ samplerData.tAddressMode = "clampToEdge"; >+ if (samplerData.minFilter == undefined) >+ samplerData.minFilter = "nearest"; >+ if (samplerData.magFilter == undefined) >+ samplerData.magFilter = "nearest"; >+ if (samplerData.mipFilter == undefined) >+ samplerData.mipFilter = "nearest"; >+ if (samplerData.lodMinClamp == undefined) >+ samplerData.lodMinClamp = 0; >+ if (samplerData.lodMaxClamp == undefined) >+ samplerData.lodMaxClamp = Number.MAX_VALUE; >+ if (samplerData.maxAnisotropy == undefined) >+ samplerData.maxAnisotropy = 1; >+ if (samplerData.compareFunction == undefined) >+ samplerData.compareFunction = "never"; >+ if (samplerData.borderColor == undefined) >+ samplerData.borderColor = "transparentBlack"; >+ return TypedValue.box(program.intrinsics.sampler, samplerData); >+} >+ >+function make1DTexture(program, mipmaps, elementType) >+{ >+ return TypedValue.box(program.intrinsics[`Texture1D<${elementType}>`], new Texture1D(elementType, mipmaps)); >+} >+ >+function make1DTextureArray(program, array, elementType) >+{ >+ return TypedValue.box(program.intrinsics[`Texture1DArray<${elementType}>`], new Texture1DArray(elementType, array)); >+} >+ >+function make2DTexture(program, mipmaps, elementType) >+{ >+ return TypedValue.box(program.intrinsics[`Texture2D<${elementType}>`], new Texture2D(elementType, mipmaps)); >+} >+ >+function make2DTextureArray(program, array, elementType) >+{ >+ return TypedValue.box(program.intrinsics[`Texture2DArray<${elementType}>`], new Texture2DArray(elementType, array)); >+} >+ >+function make3DTexture(program, mipmaps, elementType) >+{ >+ return TypedValue.box(program.intrinsics[`Texture3D<${elementType}>`], new Texture3D(elementType, mipmaps)); >+} >+ >+function makeTextureCube(program, array, elementType) >+{ >+ return TypedValue.box(program.intrinsics[`TextureCube<${elementType}>`], new TextureCube(elementType, array)); >+} >+ >+function makeRW1DTexture(program, elements, elementType) >+{ >+ return TypedValue.box(program.intrinsics[`RWTexture1D<${elementType}>`], new Texture1DRW(elementType, elements)); >+} >+ >+function makeRW1DTextureArray(program, array, elementType) >+{ >+ return TypedValue.box(program.intrinsics[`RWTexture1DArray<${elementType}>`], new Texture1DArrayRW(elementType, array)); >+} >+ >+function makeRW2DTexture(program, rows, elementType) >+{ >+ return TypedValue.box(program.intrinsics[`RWTexture2D<${elementType}>`], new Texture2DRW(elementType, rows)); >+} >+ >+function makeRW2DTextureArray(program, array, elementType) >+{ >+ return TypedValue.box(program.intrinsics[`RWTexture2DArray<${elementType}>`], new Texture2DArrayRW(elementType, array)); >+} >+ >+function makeRW3DTexture(program, depthSlices, elementType) >+{ >+ return TypedValue.box(program.intrinsics[`RWTexture3D<${elementType}>`], new Texture3DRW(elementType, depthSlices)); >+} >+ > function checkNumber(program, result, expected) > { > if (!result.type.unifyNode.isNumber) >@@ -5582,7 +5720,743 @@ tests.arrayIndex = function() { > checkInt(program, callFunction(program, "arrayIndexing", [ makeUint(program, 0), makeUint(program, 2) ]), 3); > checkInt(program, callFunction(program, "arrayIndexing", [ makeUint(program, 1), makeUint(program, 0) ]), 4); > checkInt(program, callFunction(program, "arrayIndexing", [ makeUint(program, 1), makeUint(program, 1) ]), 5); >- checkInt(program, callFunction(program, "arrayIndexing", [ makeUint(program, 1), makeUint(program, 2) ]), 6); >+ checkInt(program, callFunction(program, "arrayIndexing", [ makeUint(program, 1), makeUint(program, 2) ]), 6); >+} >+ >+function createTexturesForTesting(program) >+{ >+ let texture1D = make1DTexture(program, [[1, 7, 14, 79], [13, 16], [15]], "float"); >+ let texture1DArray = make1DTextureArray(program, [[[1, 7, 14, 79], [13, 16], [15]], [[16, 17, 18, 19], [20, 21], [22]]], "float"); >+ let texture2D = make2DTexture(program, [ >+ [[1, 2, 3, 4, 5, 6, 7, 8], >+ [9, 10, 11, 12, 13, 14, 15, 16], >+ [17, 18, 19, 20, 21, 22, 23, 24], >+ [25, 26, 27, 28, 29, 30, 31, 32]], >+ [[33, 34, 35, 36], >+ [37, 38, 39, 40]], >+ [[41, 42]] >+ ], "float"); >+ let texture2DArray = make2DTextureArray(program, [[ >+ [[1, 2, 3, 4, 5, 6, 7, 8], >+ [9, 10, 11, 12, 13, 14, 15, 16], >+ [17, 18, 19, 20, 21, 22, 23, 24], >+ [25, 26, 27, 28, 29, 30, 31, 32]], >+ [[33, 34, 35, 36], >+ [37, 38, 39, 40]], >+ [[41, 42]] >+ ], [ >+ [[43, 44, 45, 46, 47, 48, 49, 50], >+ [51, 52, 53, 54, 55, 56, 57, 58], >+ [59, 60, 61, 62, 63, 64, 65, 66], >+ [67, 68, 69, 70, 71, 72, 73, 74]], >+ [[75, 76, 77, 78], >+ [79, 80, 81, 82]], >+ [[83, 84]] >+ ]], "float"); >+ let texture3D = make3DTexture(program, [ >+ [[[1, 2, 3, 4, 5, 6, 7, 8], >+ [9, 10, 11, 12, 13, 14, 15, 16], >+ [17, 18, 19, 20, 21, 22, 23, 24], >+ [25, 26, 27, 28, 29, 30, 31, 32]], >+ [[33, 34, 35, 36, 37, 38, 39, 40], >+ [41, 42, 43, 44, 45, 46, 47, 48], >+ [49, 50, 51, 52, 53, 54, 55, 56], >+ [57, 58, 59, 60, 61, 62, 63, 64]]], >+ [[[65, 66, 67, 68], >+ [69, 70, 71, 72]]] >+ ], "float"); >+ let textureCube = makeTextureCube(program, [[ >+ [[1, 2], >+ [3, 4], >+ [5, 6], >+ [7, 8]], >+ [[9], >+ [10]], >+ ], [ >+ [[11, 12], >+ [13, 14], >+ [15, 16], >+ [17, 18]], >+ [[19], >+ [20]], >+ ], [ >+ [[21, 22], >+ [23, 24], >+ [25, 26], >+ [27, 28]], >+ [[29], >+ [30]], >+ ], [ >+ [[31, 32], >+ [33, 34], >+ [35, 36], >+ [37, 38]], >+ [[39], >+ [40]], >+ ], [ >+ [[41, 42], >+ [43, 44], >+ [45, 46], >+ [47, 48]], >+ [[49], >+ [50]], >+ ], [ >+ [[51, 52], >+ [53, 54], >+ [55, 56], >+ [57, 58]], >+ [[59], >+ [60]], >+ ]], "float"); >+ let rwTexture1D = makeRW1DTexture(program, [1, 2, 3, 4, 5, 6, 7, 8], "float"); >+ let rwTexture1DArray = makeRW1DTextureArray(program, [[1, 2, 3, 4, 5, 6, 7, 8], [9, 10, 11, 12, 13, 14, 15, 16], [17, 18, 19, 20, 21, 22, 23, 24]], "float"); >+ let rwTexture2D = makeRW2DTexture(program, [ >+ [1, 2, 3, 4, 5, 6, 7, 8], >+ [9, 10, 11, 12, 13, 14, 15, 16], >+ [17, 18, 19, 20, 21, 22, 23, 24], >+ [25, 26, 27, 28, 29, 30, 31, 32]], "float"); >+ let rwTexture2DArray = makeRW2DTextureArray(program, [ >+ [[1, 2, 3, 4, 5, 6, 7, 8], >+ [9, 10, 11, 12, 13, 14, 15, 16], >+ [17, 18, 19, 20, 21, 22, 23, 24], >+ [25, 26, 27, 28, 29, 30, 31, 32]], >+ [[33, 34, 35, 36, 37, 38, 39, 40], >+ [41, 42, 43, 44, 45, 46, 47, 48], >+ [49, 50, 51, 52, 53, 54, 55, 56], >+ [57, 58, 59, 60, 61, 62, 63, 64]]], "float"); >+ let rwTexture3D = makeRW3DTexture(program, [ >+ [[1, 2, 3, 4, 5, 6, 7, 8], >+ [9, 10, 11, 12, 13, 14, 15, 16], >+ [17, 18, 19, 20, 21, 22, 23, 24], >+ [25, 26, 27, 28, 29, 30, 31, 32]], >+ [[33, 34, 35, 36, 37, 38, 39, 40], >+ [41, 42, 43, 44, 45, 46, 47, 48], >+ [49, 50, 51, 52, 53, 54, 55, 56], >+ [57, 58, 59, 60, 61, 62, 63, 64]]], "float"); >+ return [texture1D, texture1DArray, texture2D, texture2DArray, texture3D, textureCube, rwTexture1D, rwTexture1DArray, rwTexture2D, rwTexture2DArray, rwTexture3D]; >+} >+ >+tests.textureDimensions = function() { >+ let program = doPrep(` >+ uint foo1(Texture1D<float> texture) { >+ uint width; >+ uint numberOfLevels; >+ GetDimensions(texture, 0, &width, &numberOfLevels); >+ return width; >+ } >+ uint foo2(Texture1D<float> texture) { >+ uint width; >+ uint numberOfLevels; >+ GetDimensions(texture, 0, &width, &numberOfLevels); >+ return numberOfLevels; >+ } >+ uint foo3(Texture1DArray<float> texture) { >+ uint width; >+ uint elements; >+ uint numberOfLevels; >+ GetDimensions(texture, 0, &width, &elements, &numberOfLevels); >+ return width; >+ } >+ uint foo4(Texture1DArray<float> texture) { >+ uint width; >+ uint elements; >+ uint numberOfLevels; >+ GetDimensions(texture, 0, &width, &elements, &numberOfLevels); >+ return elements; >+ } >+ uint foo5(Texture1DArray<float> texture) { >+ uint width; >+ uint elements; >+ uint numberOfLevels; >+ GetDimensions(texture, 0, &width, &elements, &numberOfLevels); >+ return numberOfLevels; >+ } >+ uint foo6(Texture2D<float> texture) { >+ uint width; >+ uint height; >+ uint numberOfLevels; >+ GetDimensions(texture, 0, &width, &height, &numberOfLevels); >+ return width; >+ } >+ uint foo7(Texture2D<float> texture) { >+ uint width; >+ uint height; >+ uint numberOfLevels; >+ GetDimensions(texture, 0, &width, &height, &numberOfLevels); >+ return height; >+ } >+ uint foo8(Texture2D<float> texture) { >+ uint width; >+ uint height; >+ uint numberOfLevels; >+ GetDimensions(texture, 0, &width, &height, &numberOfLevels); >+ return numberOfLevels; >+ } >+ uint foo9(Texture2DArray<float> texture) { >+ uint width; >+ uint height; >+ uint elements; >+ uint numberOfLevels; >+ GetDimensions(texture, 0, &width, &height, &elements, &numberOfLevels); >+ return width; >+ } >+ uint foo10(Texture2DArray<float> texture) { >+ uint width; >+ uint height; >+ uint elements; >+ uint numberOfLevels; >+ GetDimensions(texture, 0, &width, &height, &elements, &numberOfLevels); >+ return height; >+ } >+ uint foo11(Texture2DArray<float> texture) { >+ uint width; >+ uint height; >+ uint elements; >+ uint numberOfLevels; >+ GetDimensions(texture, 0, &width, &height, &elements, &numberOfLevels); >+ return elements; >+ } >+ uint foo12(Texture2DArray<float> texture) { >+ uint width; >+ uint height; >+ uint elements; >+ uint numberOfLevels; >+ GetDimensions(texture, 0, &width, &height, &elements, &numberOfLevels); >+ return numberOfLevels; >+ } >+ uint foo13(Texture3D<float> texture) { >+ uint width; >+ uint height; >+ uint depth; >+ uint numberOfLevels; >+ GetDimensions(texture, 0, &width, &height, &depth, &numberOfLevels); >+ return width; >+ } >+ uint foo14(Texture3D<float> texture) { >+ uint width; >+ uint height; >+ uint depth; >+ uint numberOfLevels; >+ GetDimensions(texture, 0, &width, &height, &depth, &numberOfLevels); >+ return height; >+ } >+ uint foo15(Texture3D<float> texture) { >+ uint width; >+ uint height; >+ uint depth; >+ uint numberOfLevels; >+ GetDimensions(texture, 0, &width, &height, &depth, &numberOfLevels); >+ return depth; >+ } >+ uint foo16(Texture3D<float> texture) { >+ uint width; >+ uint height; >+ uint depth; >+ uint numberOfLevels; >+ GetDimensions(texture, 0, &width, &height, &depth, &numberOfLevels); >+ return numberOfLevels; >+ } >+ uint foo17(TextureCube<float> texture) { >+ uint width; >+ uint height; >+ uint numberOfLevels; >+ GetDimensions(texture, 0, &width, &height, &numberOfLevels); >+ return width; >+ } >+ uint foo18(TextureCube<float> texture) { >+ uint width; >+ uint height; >+ uint numberOfLevels; >+ GetDimensions(texture, 0, &width, &height, &numberOfLevels); >+ return height; >+ } >+ uint foo19(TextureCube<float> texture) { >+ uint width; >+ uint height; >+ uint numberOfLevels; >+ GetDimensions(texture, 0, &width, &height, &numberOfLevels); >+ return numberOfLevels; >+ } >+ uint foo20(RWTexture1D<float> texture) { >+ uint width; >+ GetDimensions(texture, &width); >+ return width; >+ } >+ uint foo21(RWTexture1DArray<float> texture) { >+ uint width; >+ uint elements; >+ GetDimensions(texture, &width, &elements); >+ return width; >+ } >+ uint foo22(RWTexture1DArray<float> texture) { >+ uint width; >+ uint elements; >+ GetDimensions(texture, &width, &elements); >+ return elements; >+ } >+ uint foo23(RWTexture2D<float> texture) { >+ uint width; >+ uint height; >+ GetDimensions(texture, &width, &height); >+ return width; >+ } >+ uint foo24(RWTexture2D<float> texture) { >+ uint width; >+ uint height; >+ GetDimensions(texture, &width, &height); >+ return height; >+ } >+ uint foo25(RWTexture2DArray<float> texture) { >+ uint width; >+ uint height; >+ uint elements; >+ GetDimensions(texture, &width, &height, &elements); >+ return width; >+ } >+ uint foo26(RWTexture2DArray<float> texture) { >+ uint width; >+ uint height; >+ uint elements; >+ GetDimensions(texture, &width, &height, &elements); >+ return height; >+ } >+ uint foo27(RWTexture2DArray<float> texture) { >+ uint width; >+ uint height; >+ uint elements; >+ GetDimensions(texture, &width, &height, &elements); >+ return elements; >+ } >+ uint foo28(RWTexture3D<float> texture) { >+ uint width; >+ uint height; >+ uint depth; >+ GetDimensions(texture, &width, &height, &depth); >+ return width; >+ } >+ uint foo29(RWTexture3D<float> texture) { >+ uint width; >+ uint height; >+ uint depth; >+ GetDimensions(texture, &width, &height, &depth); >+ return height; >+ } >+ uint foo30(RWTexture3D<float> texture) { >+ uint width; >+ uint height; >+ uint depth; >+ GetDimensions(texture, &width, &height, &depth); >+ return depth; >+ } >+ `); >+ let [texture1D, texture1DArray, texture2D, texture2DArray, texture3D, textureCube, rwTexture1D, rwTexture1DArray, rwTexture2D, rwTexture2DArray, rwTexture3D] = createTexturesForTesting(program); >+ checkUint(program, callFunction(program, "foo1", [texture1D]), 4); >+ checkUint(program, callFunction(program, "foo2", [texture1D]), 3); >+ checkUint(program, callFunction(program, "foo3", [texture1DArray]), 4); >+ checkUint(program, callFunction(program, "foo4", [texture1DArray]), 2); >+ checkUint(program, callFunction(program, "foo5", [texture1DArray]), 3); >+ checkUint(program, callFunction(program, "foo6", [texture2D]), 8); >+ checkUint(program, callFunction(program, "foo7", [texture2D]), 4); >+ checkUint(program, callFunction(program, "foo8", [texture2D]), 3); >+ checkUint(program, callFunction(program, "foo9", [texture2DArray]), 8); >+ checkUint(program, callFunction(program, "foo10", [texture2DArray]), 4); >+ checkUint(program, callFunction(program, "foo11", [texture2DArray]), 2); >+ checkUint(program, callFunction(program, "foo12", [texture2DArray]), 3); >+ checkUint(program, callFunction(program, "foo13", [texture3D]), 8); >+ checkUint(program, callFunction(program, "foo14", [texture3D]), 4); >+ checkUint(program, callFunction(program, "foo15", [texture3D]), 2); >+ checkUint(program, callFunction(program, "foo16", [texture3D]), 2); >+ checkUint(program, callFunction(program, "foo17", [textureCube]), 2); >+ checkUint(program, callFunction(program, "foo18", [textureCube]), 4); >+ checkUint(program, callFunction(program, "foo19", [textureCube]), 2); >+ checkUint(program, callFunction(program, "foo20", [rwTexture1D]), 8); >+ checkUint(program, callFunction(program, "foo21", [rwTexture1DArray]), 8); >+ checkUint(program, callFunction(program, "foo22", [rwTexture1DArray]), 3); >+ checkUint(program, callFunction(program, "foo23", [rwTexture2D]), 8); >+ checkUint(program, callFunction(program, "foo24", [rwTexture2D]), 4); >+ checkUint(program, callFunction(program, "foo25", [rwTexture2DArray]), 8); >+ checkUint(program, callFunction(program, "foo26", [rwTexture2DArray]), 4); >+ checkUint(program, callFunction(program, "foo27", [rwTexture2DArray]), 2); >+ checkUint(program, callFunction(program, "foo28", [rwTexture3D]), 8); >+ checkUint(program, callFunction(program, "foo29", [rwTexture3D]), 4); >+ checkUint(program, callFunction(program, "foo30", [rwTexture3D]), 2); >+} >+ >+tests.textureLoad = function() { >+ let program = doPrep(` >+ float foo1(Texture1D<float> texture, int location, int mipmap) { >+ return Load(texture, int2(location, mipmap)); >+ } >+ float foo2(Texture1D<float> texture, int location, int mipmap, int offset) { >+ return Load(texture, int2(location, mipmap), offset); >+ } >+ float foo3(Texture1DArray<float> texture, int location, int mipmap, int layer) { >+ return Load(texture, int3(location, mipmap, layer)); >+ } >+ float foo4(Texture1DArray<float> texture, int location, int mipmap, int layer, int offset) { >+ return Load(texture, int3(location, mipmap, layer), offset); >+ } >+ float foo5(Texture2D<float> texture, int x, int y, int mipmap) { >+ return Load(texture, int3(x, y, mipmap)); >+ } >+ float foo6(Texture2D<float> texture, int x, int y, int mipmap, int offsetX, int offsetY) { >+ return Load(texture, int3(x, y, mipmap), int2(offsetX, offsetY)); >+ } >+ float foo7(Texture2DArray<float> texture, int x, int y, int mipmap, int layer) { >+ return Load(texture, int4(x, y, mipmap, layer)); >+ } >+ float foo8(Texture2DArray<float> texture, int x, int y, int mipmap, int layer, int offsetX, int offsetY) { >+ return Load(texture, int4(x, y, mipmap, layer), int2(offsetX, offsetY)); >+ } >+ float foo9(Texture3D<float> texture, int x, int y, int z, int mipmap) { >+ return Load(texture, int4(x, y, z, mipmap)); >+ } >+ float foo10(Texture3D<float> texture, int x, int y, int z, int mipmap, int offsetX, int offsetY, int offsetZ) { >+ return Load(texture, int4(x, y, z, mipmap), int3(offsetX, offsetY, offsetZ)); >+ } >+ float foo11(RWTexture1D<float> texture, int location) { >+ return Load(texture, location); >+ } >+ float foo12(RWTexture1DArray<float> texture, int location, int layer) { >+ return Load(texture, int2(location, layer)); >+ } >+ float foo13(RWTexture2D<float> texture, int x, int y) { >+ return Load(texture, int2(x, y)); >+ } >+ float foo14(RWTexture2DArray<float> texture, int x, int y, int layer) { >+ return Load(texture, int3(x, y, layer)); >+ } >+ float foo15(RWTexture3D<float> texture, int x, int y, int z) { >+ return Load(texture, int3(x, y, z)); >+ } >+ `); >+ let [texture1D, texture1DArray, texture2D, texture2DArray, texture3D, textureCube, rwTexture1D, rwTexture1DArray, rwTexture2D, rwTexture2DArray, rwTexture3D] = createTexturesForTesting(program); >+ checkFloat(program, callFunction(program, "foo1", [texture1D, makeInt(program, 0), makeInt(program, 0)]), 1); >+ checkFloat(program, callFunction(program, "foo1", [texture1D, makeInt(program, 1), makeInt(program, 0)]), 7); >+ checkFloat(program, callFunction(program, "foo1", [texture1D, makeInt(program, 0), makeInt(program, 1)]), 13); >+ checkFloat(program, callFunction(program, "foo1", [texture1D, makeInt(program, 1), makeInt(program, 1)]), 16); >+ checkFloat(program, callFunction(program, "foo2", [texture1D, makeInt(program, 0), makeInt(program, 0), makeInt(program, 1)]), 7); >+ checkFloat(program, callFunction(program, "foo2", [texture1D, makeInt(program, 1), makeInt(program, 0), makeInt(program, -1)]), 1); >+ checkFloat(program, callFunction(program, "foo2", [texture1D, makeInt(program, 0), makeInt(program, 1), makeInt(program, 1)]), 16); >+ checkFloat(program, callFunction(program, "foo2", [texture1D, makeInt(program, 1), makeInt(program, 1), makeInt(program, -1)]), 13); >+ checkFloat(program, callFunction(program, "foo3", [texture1DArray, makeInt(program, 0), makeInt(program, 0), makeInt(program, 0)]), 1); >+ checkFloat(program, callFunction(program, "foo3", [texture1DArray, makeInt(program, 1), makeInt(program, 0), makeInt(program, 0)]), 7); >+ checkFloat(program, callFunction(program, "foo3", [texture1DArray, makeInt(program, 0), makeInt(program, 1), makeInt(program, 0)]), 13); >+ checkFloat(program, callFunction(program, "foo3", [texture1DArray, makeInt(program, 1), makeInt(program, 1), makeInt(program, 0)]), 16); >+ checkFloat(program, callFunction(program, "foo3", [texture1DArray, makeInt(program, 0), makeInt(program, 0), makeInt(program, 1)]), 16); >+ checkFloat(program, callFunction(program, "foo3", [texture1DArray, makeInt(program, 1), makeInt(program, 0), makeInt(program, 1)]), 17); >+ checkFloat(program, callFunction(program, "foo3", [texture1DArray, makeInt(program, 0), makeInt(program, 1), makeInt(program, 1)]), 20); >+ checkFloat(program, callFunction(program, "foo3", [texture1DArray, makeInt(program, 1), makeInt(program, 1), makeInt(program, 1)]), 21); >+ checkFloat(program, callFunction(program, "foo4", [texture1DArray, makeInt(program, 0), makeInt(program, 0), makeInt(program, 0), makeInt(program, 1)]), 7); >+ checkFloat(program, callFunction(program, "foo4", [texture1DArray, makeInt(program, 1), makeInt(program, 0), makeInt(program, 0), makeInt(program, -1)]), 1); >+ checkFloat(program, callFunction(program, "foo4", [texture1DArray, makeInt(program, 0), makeInt(program, 1), makeInt(program, 0), makeInt(program, 1)]), 16); >+ checkFloat(program, callFunction(program, "foo4", [texture1DArray, makeInt(program, 1), makeInt(program, 1), makeInt(program, 0), makeInt(program, -1)]), 13); >+ checkFloat(program, callFunction(program, "foo4", [texture1DArray, makeInt(program, 0), makeInt(program, 0), makeInt(program, 1), makeInt(program, 1)]), 17); >+ checkFloat(program, callFunction(program, "foo4", [texture1DArray, makeInt(program, 1), makeInt(program, 0), makeInt(program, 1), makeInt(program, -1)]), 16); >+ checkFloat(program, callFunction(program, "foo4", [texture1DArray, makeInt(program, 0), makeInt(program, 1), makeInt(program, 1), makeInt(program, 1)]), 21); >+ checkFloat(program, callFunction(program, "foo4", [texture1DArray, makeInt(program, 1), makeInt(program, 1), makeInt(program, 1), makeInt(program, -1)]), 20); >+ checkFloat(program, callFunction(program, "foo5", [texture2D, makeInt(program, 0), makeInt(program, 0), makeInt(program, 0)]), 1); >+ checkFloat(program, callFunction(program, "foo5", [texture2D, makeInt(program, 1), makeInt(program, 0), makeInt(program, 0)]), 2); >+ checkFloat(program, callFunction(program, "foo5", [texture2D, makeInt(program, 0), makeInt(program, 1), makeInt(program, 0)]), 9); >+ checkFloat(program, callFunction(program, "foo5", [texture2D, makeInt(program, 1), makeInt(program, 1), makeInt(program, 0)]), 10); >+ checkFloat(program, callFunction(program, "foo5", [texture2D, makeInt(program, 0), makeInt(program, 0), makeInt(program, 1)]), 33); >+ checkFloat(program, callFunction(program, "foo5", [texture2D, makeInt(program, 1), makeInt(program, 0), makeInt(program, 1)]), 34); >+ checkFloat(program, callFunction(program, "foo5", [texture2D, makeInt(program, 0), makeInt(program, 1), makeInt(program, 1)]), 37); >+ checkFloat(program, callFunction(program, "foo5", [texture2D, makeInt(program, 1), makeInt(program, 1), makeInt(program, 1)]), 38); >+ checkFloat(program, callFunction(program, "foo6", [texture2D, makeInt(program, 0), makeInt(program, 0), makeInt(program, 0), makeInt(program, 1), makeInt(program, 0)]), 2); >+ checkFloat(program, callFunction(program, "foo6", [texture2D, makeInt(program, 0), makeInt(program, 0), makeInt(program, 0), makeInt(program, 1), makeInt(program, 1)]), 10); >+ checkFloat(program, callFunction(program, "foo6", [texture2D, makeInt(program, 1), makeInt(program, 0), makeInt(program, 0), makeInt(program, -1), makeInt(program, 0)]), 1); >+ checkFloat(program, callFunction(program, "foo6", [texture2D, makeInt(program, 1), makeInt(program, 0), makeInt(program, 0), makeInt(program, -1), makeInt(program, 1)]), 9); >+ checkFloat(program, callFunction(program, "foo6", [texture2D, makeInt(program, 0), makeInt(program, 1), makeInt(program, 0), makeInt(program, 1), makeInt(program, 0)]), 10); >+ checkFloat(program, callFunction(program, "foo6", [texture2D, makeInt(program, 0), makeInt(program, 1), makeInt(program, 0), makeInt(program, 1), makeInt(program, 1)]), 18); >+ checkFloat(program, callFunction(program, "foo6", [texture2D, makeInt(program, 1), makeInt(program, 1), makeInt(program, 0), makeInt(program, -1), makeInt(program, 0)]), 9); >+ checkFloat(program, callFunction(program, "foo6", [texture2D, makeInt(program, 1), makeInt(program, 1), makeInt(program, 0), makeInt(program, -1), makeInt(program, 1)]), 17); >+ checkFloat(program, callFunction(program, "foo6", [texture2D, makeInt(program, 0), makeInt(program, 0), makeInt(program, 1), makeInt(program, 1), makeInt(program, 0)]), 34); >+ checkFloat(program, callFunction(program, "foo6", [texture2D, makeInt(program, 0), makeInt(program, 0), makeInt(program, 1), makeInt(program, 1), makeInt(program, 1)]), 38); >+ checkFloat(program, callFunction(program, "foo6", [texture2D, makeInt(program, 1), makeInt(program, 0), makeInt(program, 1), makeInt(program, -1), makeInt(program, 0)]), 33); >+ checkFloat(program, callFunction(program, "foo6", [texture2D, makeInt(program, 1), makeInt(program, 0), makeInt(program, 1), makeInt(program, -1), makeInt(program, 1)]), 37); >+ checkFloat(program, callFunction(program, "foo6", [texture2D, makeInt(program, 0), makeInt(program, 1), makeInt(program, 1), makeInt(program, 1), makeInt(program, 0)]), 38); >+ checkFloat(program, callFunction(program, "foo6", [texture2D, makeInt(program, 0), makeInt(program, 1), makeInt(program, 1), makeInt(program, 1), makeInt(program, -1)]), 34); >+ checkFloat(program, callFunction(program, "foo6", [texture2D, makeInt(program, 1), makeInt(program, 1), makeInt(program, 1), makeInt(program, -1), makeInt(program, 0)]), 37); >+ checkFloat(program, callFunction(program, "foo6", [texture2D, makeInt(program, 1), makeInt(program, 1), makeInt(program, 1), makeInt(program, -1), makeInt(program, -1)]), 33); >+ checkFloat(program, callFunction(program, "foo7", [texture2DArray, makeInt(program, 0), makeInt(program, 0), makeInt(program, 0), makeInt(program, 0)]), 1); >+ checkFloat(program, callFunction(program, "foo7", [texture2DArray, makeInt(program, 1), makeInt(program, 0), makeInt(program, 0), makeInt(program, 0)]), 2); >+ checkFloat(program, callFunction(program, "foo7", [texture2DArray, makeInt(program, 0), makeInt(program, 1), makeInt(program, 0), makeInt(program, 0)]), 9); >+ checkFloat(program, callFunction(program, "foo7", [texture2DArray, makeInt(program, 1), makeInt(program, 1), makeInt(program, 0), makeInt(program, 0)]), 10); >+ checkFloat(program, callFunction(program, "foo7", [texture2DArray, makeInt(program, 0), makeInt(program, 0), makeInt(program, 1), makeInt(program, 0)]), 33); >+ checkFloat(program, callFunction(program, "foo7", [texture2DArray, makeInt(program, 1), makeInt(program, 0), makeInt(program, 1), makeInt(program, 0)]), 34); >+ checkFloat(program, callFunction(program, "foo7", [texture2DArray, makeInt(program, 0), makeInt(program, 1), makeInt(program, 1), makeInt(program, 0)]), 37); >+ checkFloat(program, callFunction(program, "foo7", [texture2DArray, makeInt(program, 1), makeInt(program, 1), makeInt(program, 1), makeInt(program, 0)]), 38); >+ checkFloat(program, callFunction(program, "foo7", [texture2DArray, makeInt(program, 0), makeInt(program, 0), makeInt(program, 0), makeInt(program, 1)]), 43); >+ checkFloat(program, callFunction(program, "foo7", [texture2DArray, makeInt(program, 1), makeInt(program, 0), makeInt(program, 0), makeInt(program, 1)]), 44); >+ checkFloat(program, callFunction(program, "foo7", [texture2DArray, makeInt(program, 0), makeInt(program, 1), makeInt(program, 0), makeInt(program, 1)]), 51); >+ checkFloat(program, callFunction(program, "foo7", [texture2DArray, makeInt(program, 1), makeInt(program, 1), makeInt(program, 0), makeInt(program, 1)]), 52); >+ checkFloat(program, callFunction(program, "foo7", [texture2DArray, makeInt(program, 0), makeInt(program, 0), makeInt(program, 1), makeInt(program, 1)]), 75); >+ checkFloat(program, callFunction(program, "foo7", [texture2DArray, makeInt(program, 1), makeInt(program, 0), makeInt(program, 1), makeInt(program, 1)]), 76); >+ checkFloat(program, callFunction(program, "foo7", [texture2DArray, makeInt(program, 0), makeInt(program, 1), makeInt(program, 1), makeInt(program, 1)]), 79); >+ checkFloat(program, callFunction(program, "foo7", [texture2DArray, makeInt(program, 1), makeInt(program, 1), makeInt(program, 1), makeInt(program, 1)]), 80); >+ checkFloat(program, callFunction(program, "foo8", [texture2DArray, makeInt(program, 0), makeInt(program, 0), makeInt(program, 0), makeInt(program, 0), makeInt(program, 1), makeInt(program, 0)]), 2); >+ checkFloat(program, callFunction(program, "foo8", [texture2DArray, makeInt(program, 0), makeInt(program, 0), makeInt(program, 0), makeInt(program, 0), makeInt(program, 1), makeInt(program, 1)]), 10); >+ checkFloat(program, callFunction(program, "foo8", [texture2DArray, makeInt(program, 1), makeInt(program, 0), makeInt(program, 0), makeInt(program, 0), makeInt(program, 1), makeInt(program, 0)]), 3); >+ checkFloat(program, callFunction(program, "foo8", [texture2DArray, makeInt(program, 1), makeInt(program, 0), makeInt(program, 0), makeInt(program, 0), makeInt(program, 1), makeInt(program, 1)]), 11); >+ checkFloat(program, callFunction(program, "foo8", [texture2DArray, makeInt(program, 0), makeInt(program, 1), makeInt(program, 0), makeInt(program, 0), makeInt(program, 1), makeInt(program, 0)]), 10); >+ checkFloat(program, callFunction(program, "foo8", [texture2DArray, makeInt(program, 0), makeInt(program, 1), makeInt(program, 0), makeInt(program, 0), makeInt(program, 1), makeInt(program, 1)]), 18); >+ checkFloat(program, callFunction(program, "foo8", [texture2DArray, makeInt(program, 1), makeInt(program, 1), makeInt(program, 0), makeInt(program, 0), makeInt(program, 1), makeInt(program, 0)]), 11); >+ checkFloat(program, callFunction(program, "foo8", [texture2DArray, makeInt(program, 1), makeInt(program, 1), makeInt(program, 0), makeInt(program, 0), makeInt(program, 1), makeInt(program, 1)]), 19); >+ checkFloat(program, callFunction(program, "foo8", [texture2DArray, makeInt(program, 0), makeInt(program, 0), makeInt(program, 1), makeInt(program, 0), makeInt(program, 1), makeInt(program, 0)]), 34); >+ checkFloat(program, callFunction(program, "foo8", [texture2DArray, makeInt(program, 0), makeInt(program, 0), makeInt(program, 1), makeInt(program, 0), makeInt(program, 1), makeInt(program, 1)]), 38); >+ checkFloat(program, callFunction(program, "foo8", [texture2DArray, makeInt(program, 1), makeInt(program, 0), makeInt(program, 1), makeInt(program, 0), makeInt(program, 1), makeInt(program, 0)]), 35); >+ checkFloat(program, callFunction(program, "foo8", [texture2DArray, makeInt(program, 1), makeInt(program, 0), makeInt(program, 1), makeInt(program, 0), makeInt(program, 1), makeInt(program, 1)]), 39); >+ checkFloat(program, callFunction(program, "foo8", [texture2DArray, makeInt(program, 0), makeInt(program, 1), makeInt(program, 1), makeInt(program, 0), makeInt(program, 1), makeInt(program, 0)]), 38); >+ checkFloat(program, callFunction(program, "foo8", [texture2DArray, makeInt(program, 0), makeInt(program, 1), makeInt(program, 1), makeInt(program, 0), makeInt(program, 1), makeInt(program, -1)]), 34); >+ checkFloat(program, callFunction(program, "foo8", [texture2DArray, makeInt(program, 1), makeInt(program, 1), makeInt(program, 1), makeInt(program, 0), makeInt(program, 1), makeInt(program, 0)]), 39); >+ checkFloat(program, callFunction(program, "foo8", [texture2DArray, makeInt(program, 1), makeInt(program, 1), makeInt(program, 1), makeInt(program, 0), makeInt(program, 1), makeInt(program, -1)]), 35); >+ checkFloat(program, callFunction(program, "foo8", [texture2DArray, makeInt(program, 0), makeInt(program, 0), makeInt(program, 0), makeInt(program, 1), makeInt(program, 1), makeInt(program, 0)]), 44); >+ checkFloat(program, callFunction(program, "foo8", [texture2DArray, makeInt(program, 0), makeInt(program, 0), makeInt(program, 0), makeInt(program, 1), makeInt(program, 1), makeInt(program, 1)]), 52); >+ checkFloat(program, callFunction(program, "foo8", [texture2DArray, makeInt(program, 1), makeInt(program, 0), makeInt(program, 0), makeInt(program, 1), makeInt(program, 1), makeInt(program, 0)]), 45); >+ checkFloat(program, callFunction(program, "foo8", [texture2DArray, makeInt(program, 1), makeInt(program, 0), makeInt(program, 0), makeInt(program, 1), makeInt(program, 1), makeInt(program, 1)]), 53); >+ checkFloat(program, callFunction(program, "foo8", [texture2DArray, makeInt(program, 0), makeInt(program, 1), makeInt(program, 0), makeInt(program, 1), makeInt(program, 1), makeInt(program, 0)]), 52); >+ checkFloat(program, callFunction(program, "foo8", [texture2DArray, makeInt(program, 0), makeInt(program, 1), makeInt(program, 0), makeInt(program, 1), makeInt(program, 1), makeInt(program, 1)]), 60); >+ checkFloat(program, callFunction(program, "foo8", [texture2DArray, makeInt(program, 1), makeInt(program, 1), makeInt(program, 0), makeInt(program, 1), makeInt(program, 1), makeInt(program, 0)]), 53); >+ checkFloat(program, callFunction(program, "foo8", [texture2DArray, makeInt(program, 1), makeInt(program, 1), makeInt(program, 0), makeInt(program, 1), makeInt(program, 1), makeInt(program, 1)]), 61); >+ checkFloat(program, callFunction(program, "foo8", [texture2DArray, makeInt(program, 0), makeInt(program, 0), makeInt(program, 1), makeInt(program, 1), makeInt(program, 1), makeInt(program, 0)]), 76); >+ checkFloat(program, callFunction(program, "foo8", [texture2DArray, makeInt(program, 0), makeInt(program, 0), makeInt(program, 1), makeInt(program, 1), makeInt(program, 1), makeInt(program, 1)]), 80); >+ checkFloat(program, callFunction(program, "foo8", [texture2DArray, makeInt(program, 1), makeInt(program, 0), makeInt(program, 1), makeInt(program, 1), makeInt(program, 1), makeInt(program, 0)]), 77); >+ checkFloat(program, callFunction(program, "foo8", [texture2DArray, makeInt(program, 1), makeInt(program, 0), makeInt(program, 1), makeInt(program, 1), makeInt(program, 1), makeInt(program, 1)]), 81); >+ checkFloat(program, callFunction(program, "foo8", [texture2DArray, makeInt(program, 0), makeInt(program, 1), makeInt(program, 1), makeInt(program, 1), makeInt(program, 1), makeInt(program, 0)]), 80); >+ checkFloat(program, callFunction(program, "foo8", [texture2DArray, makeInt(program, 0), makeInt(program, 1), makeInt(program, 1), makeInt(program, 1), makeInt(program, 1), makeInt(program, -1)]), 76); >+ checkFloat(program, callFunction(program, "foo8", [texture2DArray, makeInt(program, 1), makeInt(program, 1), makeInt(program, 1), makeInt(program, 1), makeInt(program, 1), makeInt(program, 0)]), 81); >+ checkFloat(program, callFunction(program, "foo8", [texture2DArray, makeInt(program, 1), makeInt(program, 1), makeInt(program, 1), makeInt(program, 1), makeInt(program, 1), makeInt(program, -1)]), 77); >+ checkFloat(program, callFunction(program, "foo9", [texture3D, makeInt(program, 0), makeInt(program, 0), makeInt(program, 0), makeInt(program, 0)]), 1); >+ checkFloat(program, callFunction(program, "foo9", [texture3D, makeInt(program, 1), makeInt(program, 0), makeInt(program, 0), makeInt(program, 0)]), 2); >+ checkFloat(program, callFunction(program, "foo9", [texture3D, makeInt(program, 0), makeInt(program, 1), makeInt(program, 0), makeInt(program, 0)]), 9); >+ checkFloat(program, callFunction(program, "foo9", [texture3D, makeInt(program, 1), makeInt(program, 1), makeInt(program, 0), makeInt(program, 0)]), 10); >+ checkFloat(program, callFunction(program, "foo9", [texture3D, makeInt(program, 0), makeInt(program, 0), makeInt(program, 1), makeInt(program, 0)]), 33); >+ checkFloat(program, callFunction(program, "foo9", [texture3D, makeInt(program, 1), makeInt(program, 0), makeInt(program, 1), makeInt(program, 0)]), 34); >+ checkFloat(program, callFunction(program, "foo9", [texture3D, makeInt(program, 0), makeInt(program, 1), makeInt(program, 1), makeInt(program, 0)]), 41); >+ checkFloat(program, callFunction(program, "foo9", [texture3D, makeInt(program, 1), makeInt(program, 1), makeInt(program, 1), makeInt(program, 0)]), 42); >+ checkFloat(program, callFunction(program, "foo9", [texture3D, makeInt(program, 0), makeInt(program, 0), makeInt(program, 0), makeInt(program, 1)]), 65); >+ checkFloat(program, callFunction(program, "foo9", [texture3D, makeInt(program, 1), makeInt(program, 0), makeInt(program, 0), makeInt(program, 1)]), 66); >+ checkFloat(program, callFunction(program, "foo9", [texture3D, makeInt(program, 0), makeInt(program, 1), makeInt(program, 0), makeInt(program, 1)]), 69); >+ checkFloat(program, callFunction(program, "foo9", [texture3D, makeInt(program, 1), makeInt(program, 1), makeInt(program, 0), makeInt(program, 1)]), 70); >+ checkFloat(program, callFunction(program, "foo10", [texture3D, makeInt(program, 0), makeInt(program, 0), makeInt(program, 0), makeInt(program, 0), makeInt(program, 1), makeInt(program, 0), makeInt(program, 0)]), 2); >+ checkFloat(program, callFunction(program, "foo10", [texture3D, makeInt(program, 0), makeInt(program, 0), makeInt(program, 0), makeInt(program, 0), makeInt(program, 0), makeInt(program, 1), makeInt(program, 0)]), 9); >+ checkFloat(program, callFunction(program, "foo10", [texture3D, makeInt(program, 0), makeInt(program, 0), makeInt(program, 0), makeInt(program, 0), makeInt(program, 0), makeInt(program, 0), makeInt(program, 1)]), 33); >+ checkFloat(program, callFunction(program, "foo10", [texture3D, makeInt(program, 1), makeInt(program, 0), makeInt(program, 0), makeInt(program, 0), makeInt(program, 1), makeInt(program, 0), makeInt(program, 0)]), 3); >+ checkFloat(program, callFunction(program, "foo10", [texture3D, makeInt(program, 1), makeInt(program, 0), makeInt(program, 0), makeInt(program, 0), makeInt(program, 0), makeInt(program, 1), makeInt(program, 0)]), 10); >+ checkFloat(program, callFunction(program, "foo10", [texture3D, makeInt(program, 1), makeInt(program, 0), makeInt(program, 0), makeInt(program, 0), makeInt(program, 0), makeInt(program, 0), makeInt(program, 1)]), 34); >+ checkFloat(program, callFunction(program, "foo10", [texture3D, makeInt(program, 0), makeInt(program, 1), makeInt(program, 0), makeInt(program, 0), makeInt(program, 1), makeInt(program, 0), makeInt(program, 0)]), 10); >+ checkFloat(program, callFunction(program, "foo10", [texture3D, makeInt(program, 0), makeInt(program, 1), makeInt(program, 0), makeInt(program, 0), makeInt(program, 0), makeInt(program, 1), makeInt(program, 0)]), 17); >+ checkFloat(program, callFunction(program, "foo10", [texture3D, makeInt(program, 0), makeInt(program, 1), makeInt(program, 0), makeInt(program, 0), makeInt(program, 0), makeInt(program, 0), makeInt(program, 1)]), 41); >+ checkFloat(program, callFunction(program, "foo10", [texture3D, makeInt(program, 1), makeInt(program, 1), makeInt(program, 0), makeInt(program, 0), makeInt(program, 1), makeInt(program, 0), makeInt(program, 0)]), 11); >+ checkFloat(program, callFunction(program, "foo10", [texture3D, makeInt(program, 1), makeInt(program, 1), makeInt(program, 0), makeInt(program, 0), makeInt(program, 0), makeInt(program, 1), makeInt(program, 0)]), 18); >+ checkFloat(program, callFunction(program, "foo10", [texture3D, makeInt(program, 1), makeInt(program, 1), makeInt(program, 0), makeInt(program, 0), makeInt(program, 0), makeInt(program, 0), makeInt(program, 1)]), 42); >+ checkFloat(program, callFunction(program, "foo10", [texture3D, makeInt(program, 0), makeInt(program, 0), makeInt(program, 1), makeInt(program, 0), makeInt(program, 1), makeInt(program, 0), makeInt(program, 0)]), 34); >+ checkFloat(program, callFunction(program, "foo10", [texture3D, makeInt(program, 0), makeInt(program, 0), makeInt(program, 1), makeInt(program, 0), makeInt(program, 0), makeInt(program, 1), makeInt(program, 0)]), 41); >+ checkFloat(program, callFunction(program, "foo10", [texture3D, makeInt(program, 0), makeInt(program, 0), makeInt(program, 1), makeInt(program, 0), makeInt(program, 0), makeInt(program, 0), makeInt(program, -1)]), 1); >+ checkFloat(program, callFunction(program, "foo10", [texture3D, makeInt(program, 1), makeInt(program, 0), makeInt(program, 1), makeInt(program, 0), makeInt(program, 1), makeInt(program, 0), makeInt(program, 0)]), 35); >+ checkFloat(program, callFunction(program, "foo10", [texture3D, makeInt(program, 1), makeInt(program, 0), makeInt(program, 1), makeInt(program, 0), makeInt(program, 0), makeInt(program, 1), makeInt(program, 0)]), 42); >+ checkFloat(program, callFunction(program, "foo10", [texture3D, makeInt(program, 1), makeInt(program, 0), makeInt(program, 1), makeInt(program, 0), makeInt(program, 0), makeInt(program, 0), makeInt(program, -1)]), 2); >+ checkFloat(program, callFunction(program, "foo10", [texture3D, makeInt(program, 0), makeInt(program, 1), makeInt(program, 1), makeInt(program, 0), makeInt(program, 1), makeInt(program, 0), makeInt(program, 0)]), 42); >+ checkFloat(program, callFunction(program, "foo10", [texture3D, makeInt(program, 0), makeInt(program, 1), makeInt(program, 1), makeInt(program, 0), makeInt(program, 0), makeInt(program, 1), makeInt(program, 0)]), 49); >+ checkFloat(program, callFunction(program, "foo10", [texture3D, makeInt(program, 0), makeInt(program, 1), makeInt(program, 1), makeInt(program, 0), makeInt(program, 0), makeInt(program, 0), makeInt(program, -1)]), 9); >+ checkFloat(program, callFunction(program, "foo10", [texture3D, makeInt(program, 1), makeInt(program, 1), makeInt(program, 1), makeInt(program, 0), makeInt(program, 1), makeInt(program, 0), makeInt(program, 0)]), 43); >+ checkFloat(program, callFunction(program, "foo10", [texture3D, makeInt(program, 1), makeInt(program, 1), makeInt(program, 1), makeInt(program, 0), makeInt(program, 0), makeInt(program, 1), makeInt(program, 0)]), 50); >+ checkFloat(program, callFunction(program, "foo10", [texture3D, makeInt(program, 1), makeInt(program, 1), makeInt(program, 1), makeInt(program, 0), makeInt(program, 0), makeInt(program, 0), makeInt(program, -1)]), 10); >+ checkFloat(program, callFunction(program, "foo10", [texture3D, makeInt(program, 0), makeInt(program, 0), makeInt(program, 0), makeInt(program, 1), makeInt(program, 1), makeInt(program, 0), makeInt(program, 0)]), 66); >+ checkFloat(program, callFunction(program, "foo10", [texture3D, makeInt(program, 0), makeInt(program, 0), makeInt(program, 0), makeInt(program, 1), makeInt(program, 0), makeInt(program, 1), makeInt(program, 0)]), 69); >+ checkFloat(program, callFunction(program, "foo10", [texture3D, makeInt(program, 1), makeInt(program, 0), makeInt(program, 0), makeInt(program, 1), makeInt(program, 1), makeInt(program, 0), makeInt(program, 0)]), 67); >+ checkFloat(program, callFunction(program, "foo10", [texture3D, makeInt(program, 1), makeInt(program, 0), makeInt(program, 0), makeInt(program, 1), makeInt(program, 0), makeInt(program, 1), makeInt(program, 0)]), 70); >+ checkFloat(program, callFunction(program, "foo10", [texture3D, makeInt(program, 0), makeInt(program, 1), makeInt(program, 0), makeInt(program, 1), makeInt(program, 1), makeInt(program, 0), makeInt(program, 0)]), 70); >+ checkFloat(program, callFunction(program, "foo10", [texture3D, makeInt(program, 0), makeInt(program, 1), makeInt(program, 0), makeInt(program, 1), makeInt(program, 0), makeInt(program, -1), makeInt(program, 0)]), 65); >+ checkFloat(program, callFunction(program, "foo10", [texture3D, makeInt(program, 1), makeInt(program, 1), makeInt(program, 0), makeInt(program, 1), makeInt(program, 1), makeInt(program, 0), makeInt(program, 0)]), 71); >+ checkFloat(program, callFunction(program, "foo10", [texture3D, makeInt(program, 1), makeInt(program, 1), makeInt(program, 0), makeInt(program, 1), makeInt(program, 0), makeInt(program, -1), makeInt(program, 0)]), 66); >+ checkFloat(program, callFunction(program, "foo11", [rwTexture1D, makeInt(program, 0)]), 1); >+ checkFloat(program, callFunction(program, "foo11", [rwTexture1D, makeInt(program, 1)]), 2); >+ checkFloat(program, callFunction(program, "foo11", [rwTexture1D, makeInt(program, 2)]), 3); >+ checkFloat(program, callFunction(program, "foo11", [rwTexture1D, makeInt(program, 3)]), 4); >+ checkFloat(program, callFunction(program, "foo11", [rwTexture1D, makeInt(program, 4)]), 5); >+ checkFloat(program, callFunction(program, "foo11", [rwTexture1D, makeInt(program, 5)]), 6); >+ checkFloat(program, callFunction(program, "foo11", [rwTexture1D, makeInt(program, 6)]), 7); >+ checkFloat(program, callFunction(program, "foo11", [rwTexture1D, makeInt(program, 7)]), 8); >+ checkFloat(program, callFunction(program, "foo12", [rwTexture1DArray, makeInt(program, 0), makeInt(program, 0)]), 1); >+ checkFloat(program, callFunction(program, "foo12", [rwTexture1DArray, makeInt(program, 1), makeInt(program, 0)]), 2); >+ checkFloat(program, callFunction(program, "foo12", [rwTexture1DArray, makeInt(program, 2), makeInt(program, 0)]), 3); >+ checkFloat(program, callFunction(program, "foo12", [rwTexture1DArray, makeInt(program, 3), makeInt(program, 0)]), 4); >+ checkFloat(program, callFunction(program, "foo12", [rwTexture1DArray, makeInt(program, 4), makeInt(program, 0)]), 5); >+ checkFloat(program, callFunction(program, "foo12", [rwTexture1DArray, makeInt(program, 5), makeInt(program, 0)]), 6); >+ checkFloat(program, callFunction(program, "foo12", [rwTexture1DArray, makeInt(program, 6), makeInt(program, 0)]), 7); >+ checkFloat(program, callFunction(program, "foo12", [rwTexture1DArray, makeInt(program, 7), makeInt(program, 0)]), 8); >+ checkFloat(program, callFunction(program, "foo12", [rwTexture1DArray, makeInt(program, 0), makeInt(program, 1)]), 9); >+ checkFloat(program, callFunction(program, "foo12", [rwTexture1DArray, makeInt(program, 1), makeInt(program, 1)]), 10); >+ checkFloat(program, callFunction(program, "foo12", [rwTexture1DArray, makeInt(program, 2), makeInt(program, 1)]), 11); >+ checkFloat(program, callFunction(program, "foo12", [rwTexture1DArray, makeInt(program, 3), makeInt(program, 1)]), 12); >+ checkFloat(program, callFunction(program, "foo12", [rwTexture1DArray, makeInt(program, 4), makeInt(program, 1)]), 13); >+ checkFloat(program, callFunction(program, "foo12", [rwTexture1DArray, makeInt(program, 5), makeInt(program, 1)]), 14); >+ checkFloat(program, callFunction(program, "foo12", [rwTexture1DArray, makeInt(program, 6), makeInt(program, 1)]), 15); >+ checkFloat(program, callFunction(program, "foo12", [rwTexture1DArray, makeInt(program, 7), makeInt(program, 1)]), 16); >+ checkFloat(program, callFunction(program, "foo12", [rwTexture1DArray, makeInt(program, 0), makeInt(program, 2)]), 17); >+ checkFloat(program, callFunction(program, "foo12", [rwTexture1DArray, makeInt(program, 1), makeInt(program, 2)]), 18); >+ checkFloat(program, callFunction(program, "foo12", [rwTexture1DArray, makeInt(program, 2), makeInt(program, 2)]), 19); >+ checkFloat(program, callFunction(program, "foo12", [rwTexture1DArray, makeInt(program, 3), makeInt(program, 2)]), 20); >+ checkFloat(program, callFunction(program, "foo12", [rwTexture1DArray, makeInt(program, 4), makeInt(program, 2)]), 21); >+ checkFloat(program, callFunction(program, "foo12", [rwTexture1DArray, makeInt(program, 5), makeInt(program, 2)]), 22); >+ checkFloat(program, callFunction(program, "foo12", [rwTexture1DArray, makeInt(program, 6), makeInt(program, 2)]), 23); >+ checkFloat(program, callFunction(program, "foo12", [rwTexture1DArray, makeInt(program, 7), makeInt(program, 2)]), 24); >+ checkFloat(program, callFunction(program, "foo13", [rwTexture2D, makeInt(program, 0), makeInt(program, 0)]), 1); >+ checkFloat(program, callFunction(program, "foo13", [rwTexture2D, makeInt(program, 1), makeInt(program, 0)]), 2); >+ checkFloat(program, callFunction(program, "foo13", [rwTexture2D, makeInt(program, 2), makeInt(program, 0)]), 3); >+ checkFloat(program, callFunction(program, "foo13", [rwTexture2D, makeInt(program, 3), makeInt(program, 0)]), 4); >+ checkFloat(program, callFunction(program, "foo13", [rwTexture2D, makeInt(program, 4), makeInt(program, 0)]), 5); >+ checkFloat(program, callFunction(program, "foo13", [rwTexture2D, makeInt(program, 5), makeInt(program, 0)]), 6); >+ checkFloat(program, callFunction(program, "foo13", [rwTexture2D, makeInt(program, 6), makeInt(program, 0)]), 7); >+ checkFloat(program, callFunction(program, "foo13", [rwTexture2D, makeInt(program, 7), makeInt(program, 0)]), 8); >+ checkFloat(program, callFunction(program, "foo13", [rwTexture2D, makeInt(program, 0), makeInt(program, 1)]), 9); >+ checkFloat(program, callFunction(program, "foo13", [rwTexture2D, makeInt(program, 1), makeInt(program, 1)]), 10); >+ checkFloat(program, callFunction(program, "foo13", [rwTexture2D, makeInt(program, 2), makeInt(program, 1)]), 11); >+ checkFloat(program, callFunction(program, "foo13", [rwTexture2D, makeInt(program, 3), makeInt(program, 1)]), 12); >+ checkFloat(program, callFunction(program, "foo13", [rwTexture2D, makeInt(program, 4), makeInt(program, 1)]), 13); >+ checkFloat(program, callFunction(program, "foo13", [rwTexture2D, makeInt(program, 5), makeInt(program, 1)]), 14); >+ checkFloat(program, callFunction(program, "foo13", [rwTexture2D, makeInt(program, 6), makeInt(program, 1)]), 15); >+ checkFloat(program, callFunction(program, "foo13", [rwTexture2D, makeInt(program, 7), makeInt(program, 1)]), 16); >+ checkFloat(program, callFunction(program, "foo13", [rwTexture2D, makeInt(program, 0), makeInt(program, 2)]), 17); >+ checkFloat(program, callFunction(program, "foo13", [rwTexture2D, makeInt(program, 1), makeInt(program, 2)]), 18); >+ checkFloat(program, callFunction(program, "foo13", [rwTexture2D, makeInt(program, 2), makeInt(program, 2)]), 19); >+ checkFloat(program, callFunction(program, "foo13", [rwTexture2D, makeInt(program, 3), makeInt(program, 2)]), 20); >+ checkFloat(program, callFunction(program, "foo13", [rwTexture2D, makeInt(program, 4), makeInt(program, 2)]), 21); >+ checkFloat(program, callFunction(program, "foo13", [rwTexture2D, makeInt(program, 5), makeInt(program, 2)]), 22); >+ checkFloat(program, callFunction(program, "foo13", [rwTexture2D, makeInt(program, 6), makeInt(program, 2)]), 23); >+ checkFloat(program, callFunction(program, "foo13", [rwTexture2D, makeInt(program, 7), makeInt(program, 2)]), 24); >+ checkFloat(program, callFunction(program, "foo13", [rwTexture2D, makeInt(program, 0), makeInt(program, 3)]), 25); >+ checkFloat(program, callFunction(program, "foo13", [rwTexture2D, makeInt(program, 1), makeInt(program, 3)]), 26); >+ checkFloat(program, callFunction(program, "foo13", [rwTexture2D, makeInt(program, 2), makeInt(program, 3)]), 27); >+ checkFloat(program, callFunction(program, "foo13", [rwTexture2D, makeInt(program, 3), makeInt(program, 3)]), 28); >+ checkFloat(program, callFunction(program, "foo13", [rwTexture2D, makeInt(program, 4), makeInt(program, 3)]), 29); >+ checkFloat(program, callFunction(program, "foo13", [rwTexture2D, makeInt(program, 5), makeInt(program, 3)]), 30); >+ checkFloat(program, callFunction(program, "foo13", [rwTexture2D, makeInt(program, 6), makeInt(program, 3)]), 31); >+ checkFloat(program, callFunction(program, "foo13", [rwTexture2D, makeInt(program, 7), makeInt(program, 3)]), 32); >+ checkFloat(program, callFunction(program, "foo14", [rwTexture2DArray, makeInt(program, 0), makeInt(program, 0), makeInt(program, 0)]), 1); >+ checkFloat(program, callFunction(program, "foo14", [rwTexture2DArray, makeInt(program, 1), makeInt(program, 0), makeInt(program, 0)]), 2); >+ checkFloat(program, callFunction(program, "foo14", [rwTexture2DArray, makeInt(program, 0), makeInt(program, 1), makeInt(program, 0)]), 9); >+ checkFloat(program, callFunction(program, "foo14", [rwTexture2DArray, makeInt(program, 1), makeInt(program, 1), makeInt(program, 0)]), 10); >+ checkFloat(program, callFunction(program, "foo14", [rwTexture2DArray, makeInt(program, 0), makeInt(program, 0), makeInt(program, 1)]), 33); >+ checkFloat(program, callFunction(program, "foo14", [rwTexture2DArray, makeInt(program, 1), makeInt(program, 0), makeInt(program, 1)]), 34); >+ checkFloat(program, callFunction(program, "foo14", [rwTexture2DArray, makeInt(program, 0), makeInt(program, 1), makeInt(program, 1)]), 41); >+ checkFloat(program, callFunction(program, "foo14", [rwTexture2DArray, makeInt(program, 1), makeInt(program, 1), makeInt(program, 1)]), 42); >+ checkFloat(program, callFunction(program, "foo15", [rwTexture3D, makeInt(program, 0), makeInt(program, 0), makeInt(program, 0)]), 1); >+ checkFloat(program, callFunction(program, "foo15", [rwTexture3D, makeInt(program, 1), makeInt(program, 0), makeInt(program, 0)]), 2); >+ checkFloat(program, callFunction(program, "foo15", [rwTexture3D, makeInt(program, 0), makeInt(program, 1), makeInt(program, 0)]), 9); >+ checkFloat(program, callFunction(program, "foo15", [rwTexture3D, makeInt(program, 1), makeInt(program, 1), makeInt(program, 0)]), 10); >+ checkFloat(program, callFunction(program, "foo15", [rwTexture3D, makeInt(program, 0), makeInt(program, 0), makeInt(program, 1)]), 33); >+ checkFloat(program, callFunction(program, "foo15", [rwTexture3D, makeInt(program, 1), makeInt(program, 0), makeInt(program, 1)]), 34); >+ checkFloat(program, callFunction(program, "foo15", [rwTexture3D, makeInt(program, 0), makeInt(program, 1), makeInt(program, 1)]), 41); >+ checkFloat(program, callFunction(program, "foo15", [rwTexture3D, makeInt(program, 1), makeInt(program, 1), makeInt(program, 1)]), 42); >+} >+ >+tests.textureStore = function() { >+ let program = doPrep(` >+ float foo1(RWTexture1D<float> texture, uint location, float value) { >+ Store(texture, value, location); >+ return Load(texture, int(location)); >+ } >+ float foo2(RWTexture1DArray<float> texture, uint location, uint layer, float value) { >+ Store(texture, value, uint2(location, layer)); >+ return Load(texture, int2(int(location), int(layer))); >+ } >+ float foo3(RWTexture2D<float> texture, uint x, uint y, float value) { >+ Store(texture, value, uint2(x, y)); >+ return Load(texture, int2(int(x), int(y))); >+ } >+ float foo4(RWTexture2DArray<float> texture, uint x, uint y, uint layer, float value) { >+ Store(texture, value, uint3(x, y, layer)); >+ return Load(texture, int3(int(x), int(y), int(layer))); >+ } >+ float foo5(RWTexture3D<float> texture, uint x, uint y, uint z, float value) { >+ Store(texture, value, uint3(x, y, z)); >+ return Load(texture, int3(int(x), int(y), int(z))); >+ } >+ `); >+ let [texture1D, texture1DArray, texture2D, texture2DArray, texture3D, textureCube, rwTexture1D, rwTexture1DArray, rwTexture2D, rwTexture2DArray, rwTexture3D] = createTexturesForTesting(program); >+ checkFloat(program, callFunction(program, "foo1", [rwTexture1D, makeUint(program, 0), makeFloat(program, 999)]), 999); >+ checkFloat(program, callFunction(program, "foo1", [rwTexture1D, makeUint(program, 1), makeFloat(program, 999)]), 999); >+ checkFloat(program, callFunction(program, "foo1", [rwTexture1D, makeUint(program, 2), makeFloat(program, 999)]), 999); >+ checkFloat(program, callFunction(program, "foo1", [rwTexture1D, makeUint(program, 3), makeFloat(program, 999)]), 999); >+ checkFloat(program, callFunction(program, "foo1", [rwTexture1D, makeUint(program, 4), makeFloat(program, 999)]), 999); >+ checkFloat(program, callFunction(program, "foo1", [rwTexture1D, makeUint(program, 5), makeFloat(program, 999)]), 999); >+ checkFloat(program, callFunction(program, "foo1", [rwTexture1D, makeUint(program, 6), makeFloat(program, 999)]), 999); >+ checkFloat(program, callFunction(program, "foo1", [rwTexture1D, makeUint(program, 7), makeFloat(program, 999)]), 999); >+ checkFloat(program, callFunction(program, "foo2", [rwTexture1DArray, makeUint(program, 0), makeUint(program, 0), makeFloat(program, 999)]), 999); >+ checkFloat(program, callFunction(program, "foo2", [rwTexture1DArray, makeUint(program, 1), makeUint(program, 0), makeFloat(program, 999)]), 999); >+ checkFloat(program, callFunction(program, "foo2", [rwTexture1DArray, makeUint(program, 2), makeUint(program, 0), makeFloat(program, 999)]), 999); >+ checkFloat(program, callFunction(program, "foo2", [rwTexture1DArray, makeUint(program, 3), makeUint(program, 0), makeFloat(program, 999)]), 999); >+ checkFloat(program, callFunction(program, "foo2", [rwTexture1DArray, makeUint(program, 4), makeUint(program, 0), makeFloat(program, 999)]), 999); >+ checkFloat(program, callFunction(program, "foo2", [rwTexture1DArray, makeUint(program, 5), makeUint(program, 0), makeFloat(program, 999)]), 999); >+ checkFloat(program, callFunction(program, "foo2", [rwTexture1DArray, makeUint(program, 6), makeUint(program, 0), makeFloat(program, 999)]), 999); >+ checkFloat(program, callFunction(program, "foo2", [rwTexture1DArray, makeUint(program, 7), makeUint(program, 0), makeFloat(program, 999)]), 999); >+ checkFloat(program, callFunction(program, "foo2", [rwTexture1DArray, makeUint(program, 0), makeUint(program, 1), makeFloat(program, 999)]), 999); >+ checkFloat(program, callFunction(program, "foo2", [rwTexture1DArray, makeUint(program, 1), makeUint(program, 1), makeFloat(program, 999)]), 999); >+ checkFloat(program, callFunction(program, "foo2", [rwTexture1DArray, makeUint(program, 2), makeUint(program, 1), makeFloat(program, 999)]), 999); >+ checkFloat(program, callFunction(program, "foo2", [rwTexture1DArray, makeUint(program, 3), makeUint(program, 1), makeFloat(program, 999)]), 999); >+ checkFloat(program, callFunction(program, "foo2", [rwTexture1DArray, makeUint(program, 4), makeUint(program, 1), makeFloat(program, 999)]), 999); >+ checkFloat(program, callFunction(program, "foo2", [rwTexture1DArray, makeUint(program, 5), makeUint(program, 1), makeFloat(program, 999)]), 999); >+ checkFloat(program, callFunction(program, "foo2", [rwTexture1DArray, makeUint(program, 6), makeUint(program, 1), makeFloat(program, 999)]), 999); >+ checkFloat(program, callFunction(program, "foo2", [rwTexture1DArray, makeUint(program, 7), makeUint(program, 1), makeFloat(program, 999)]), 999); >+ checkFloat(program, callFunction(program, "foo2", [rwTexture1DArray, makeUint(program, 0), makeUint(program, 2), makeFloat(program, 999)]), 999); >+ checkFloat(program, callFunction(program, "foo2", [rwTexture1DArray, makeUint(program, 1), makeUint(program, 2), makeFloat(program, 999)]), 999); >+ checkFloat(program, callFunction(program, "foo2", [rwTexture1DArray, makeUint(program, 2), makeUint(program, 2), makeFloat(program, 999)]), 999); >+ checkFloat(program, callFunction(program, "foo2", [rwTexture1DArray, makeUint(program, 3), makeUint(program, 2), makeFloat(program, 999)]), 999); >+ checkFloat(program, callFunction(program, "foo2", [rwTexture1DArray, makeUint(program, 4), makeUint(program, 2), makeFloat(program, 999)]), 999); >+ checkFloat(program, callFunction(program, "foo2", [rwTexture1DArray, makeUint(program, 5), makeUint(program, 2), makeFloat(program, 999)]), 999); >+ checkFloat(program, callFunction(program, "foo2", [rwTexture1DArray, makeUint(program, 6), makeUint(program, 2), makeFloat(program, 999)]), 999); >+ checkFloat(program, callFunction(program, "foo2", [rwTexture1DArray, makeUint(program, 7), makeUint(program, 2), makeFloat(program, 999)]), 999); >+ checkFloat(program, callFunction(program, "foo3", [rwTexture2D, makeUint(program, 0), makeUint(program, 0), makeFloat(program, 999)]), 999); >+ checkFloat(program, callFunction(program, "foo3", [rwTexture2D, makeUint(program, 1), makeUint(program, 0), makeFloat(program, 999)]), 999); >+ checkFloat(program, callFunction(program, "foo3", [rwTexture2D, makeUint(program, 2), makeUint(program, 0), makeFloat(program, 999)]), 999); >+ checkFloat(program, callFunction(program, "foo3", [rwTexture2D, makeUint(program, 3), makeUint(program, 0), makeFloat(program, 999)]), 999); >+ checkFloat(program, callFunction(program, "foo3", [rwTexture2D, makeUint(program, 4), makeUint(program, 0), makeFloat(program, 999)]), 999); >+ checkFloat(program, callFunction(program, "foo3", [rwTexture2D, makeUint(program, 5), makeUint(program, 0), makeFloat(program, 999)]), 999); >+ checkFloat(program, callFunction(program, "foo3", [rwTexture2D, makeUint(program, 6), makeUint(program, 0), makeFloat(program, 999)]), 999); >+ checkFloat(program, callFunction(program, "foo3", [rwTexture2D, makeUint(program, 7), makeUint(program, 0), makeFloat(program, 999)]), 999); >+ checkFloat(program, callFunction(program, "foo3", [rwTexture2D, makeUint(program, 0), makeUint(program, 1), makeFloat(program, 999)]), 999); >+ checkFloat(program, callFunction(program, "foo3", [rwTexture2D, makeUint(program, 1), makeUint(program, 1), makeFloat(program, 999)]), 999); >+ checkFloat(program, callFunction(program, "foo3", [rwTexture2D, makeUint(program, 2), makeUint(program, 1), makeFloat(program, 999)]), 999); >+ checkFloat(program, callFunction(program, "foo3", [rwTexture2D, makeUint(program, 3), makeUint(program, 1), makeFloat(program, 999)]), 999); >+ checkFloat(program, callFunction(program, "foo3", [rwTexture2D, makeUint(program, 4), makeUint(program, 1), makeFloat(program, 999)]), 999); >+ checkFloat(program, callFunction(program, "foo3", [rwTexture2D, makeUint(program, 5), makeUint(program, 1), makeFloat(program, 999)]), 999); >+ checkFloat(program, callFunction(program, "foo3", [rwTexture2D, makeUint(program, 6), makeUint(program, 1), makeFloat(program, 999)]), 999); >+ checkFloat(program, callFunction(program, "foo3", [rwTexture2D, makeUint(program, 7), makeUint(program, 1), makeFloat(program, 999)]), 999); >+ checkFloat(program, callFunction(program, "foo3", [rwTexture2D, makeUint(program, 0), makeUint(program, 2), makeFloat(program, 999)]), 999); >+ checkFloat(program, callFunction(program, "foo3", [rwTexture2D, makeUint(program, 1), makeUint(program, 2), makeFloat(program, 999)]), 999); >+ checkFloat(program, callFunction(program, "foo3", [rwTexture2D, makeUint(program, 2), makeUint(program, 2), makeFloat(program, 999)]), 999); >+ checkFloat(program, callFunction(program, "foo3", [rwTexture2D, makeUint(program, 3), makeUint(program, 2), makeFloat(program, 999)]), 999); >+ checkFloat(program, callFunction(program, "foo3", [rwTexture2D, makeUint(program, 4), makeUint(program, 2), makeFloat(program, 999)]), 999); >+ checkFloat(program, callFunction(program, "foo3", [rwTexture2D, makeUint(program, 5), makeUint(program, 2), makeFloat(program, 999)]), 999); >+ checkFloat(program, callFunction(program, "foo3", [rwTexture2D, makeUint(program, 6), makeUint(program, 2), makeFloat(program, 999)]), 999); >+ checkFloat(program, callFunction(program, "foo3", [rwTexture2D, makeUint(program, 7), makeUint(program, 2), makeFloat(program, 999)]), 999); >+ checkFloat(program, callFunction(program, "foo3", [rwTexture2D, makeUint(program, 0), makeUint(program, 3), makeFloat(program, 999)]), 999); >+ checkFloat(program, callFunction(program, "foo3", [rwTexture2D, makeUint(program, 1), makeUint(program, 3), makeFloat(program, 999)]), 999); >+ checkFloat(program, callFunction(program, "foo3", [rwTexture2D, makeUint(program, 2), makeUint(program, 3), makeFloat(program, 999)]), 999); >+ checkFloat(program, callFunction(program, "foo3", [rwTexture2D, makeUint(program, 3), makeUint(program, 3), makeFloat(program, 999)]), 999); >+ checkFloat(program, callFunction(program, "foo3", [rwTexture2D, makeUint(program, 4), makeUint(program, 3), makeFloat(program, 999)]), 999); >+ checkFloat(program, callFunction(program, "foo3", [rwTexture2D, makeUint(program, 5), makeUint(program, 3), makeFloat(program, 999)]), 999); >+ checkFloat(program, callFunction(program, "foo3", [rwTexture2D, makeUint(program, 6), makeUint(program, 3), makeFloat(program, 999)]), 999); >+ checkFloat(program, callFunction(program, "foo3", [rwTexture2D, makeUint(program, 7), makeUint(program, 3), makeFloat(program, 999)]), 999); >+ checkFloat(program, callFunction(program, "foo4", [rwTexture2DArray, makeUint(program, 0), makeUint(program, 0), makeUint(program, 0), makeFloat(program, 999)]), 999); >+ checkFloat(program, callFunction(program, "foo4", [rwTexture2DArray, makeUint(program, 1), makeUint(program, 0), makeUint(program, 0), makeFloat(program, 999)]), 999); >+ checkFloat(program, callFunction(program, "foo4", [rwTexture2DArray, makeUint(program, 0), makeUint(program, 1), makeUint(program, 0), makeFloat(program, 999)]), 999); >+ checkFloat(program, callFunction(program, "foo4", [rwTexture2DArray, makeUint(program, 1), makeUint(program, 1), makeUint(program, 0), makeFloat(program, 999)]), 999); >+ checkFloat(program, callFunction(program, "foo4", [rwTexture2DArray, makeUint(program, 0), makeUint(program, 0), makeUint(program, 1), makeFloat(program, 999)]), 999); >+ checkFloat(program, callFunction(program, "foo4", [rwTexture2DArray, makeUint(program, 1), makeUint(program, 0), makeUint(program, 1), makeFloat(program, 999)]), 999); >+ checkFloat(program, callFunction(program, "foo4", [rwTexture2DArray, makeUint(program, 0), makeUint(program, 1), makeUint(program, 1), makeFloat(program, 999)]), 999); >+ checkFloat(program, callFunction(program, "foo4", [rwTexture2DArray, makeUint(program, 1), makeUint(program, 1), makeUint(program, 1), makeFloat(program, 999)]), 999); >+ checkFloat(program, callFunction(program, "foo5", [rwTexture3D, makeUint(program, 0), makeUint(program, 0), makeUint(program, 0), makeFloat(program, 999)]), 999); >+ checkFloat(program, callFunction(program, "foo5", [rwTexture3D, makeUint(program, 1), makeUint(program, 0), makeUint(program, 0), makeFloat(program, 999)]), 999); >+ checkFloat(program, callFunction(program, "foo5", [rwTexture3D, makeUint(program, 0), makeUint(program, 1), makeUint(program, 0), makeFloat(program, 999)]), 999); >+ checkFloat(program, callFunction(program, "foo5", [rwTexture3D, makeUint(program, 1), makeUint(program, 1), makeUint(program, 0), makeFloat(program, 999)]), 999); >+ checkFloat(program, callFunction(program, "foo5", [rwTexture3D, makeUint(program, 0), makeUint(program, 0), makeUint(program, 1), makeFloat(program, 999)]), 999); >+ checkFloat(program, callFunction(program, "foo5", [rwTexture3D, makeUint(program, 1), makeUint(program, 0), makeUint(program, 1), makeFloat(program, 999)]), 999); >+ checkFloat(program, callFunction(program, "foo5", [rwTexture3D, makeUint(program, 0), makeUint(program, 1), makeUint(program, 1), makeFloat(program, 999)]), 999); >+ checkFloat(program, callFunction(program, "foo5", [rwTexture3D, makeUint(program, 1), makeUint(program, 1), makeUint(program, 1), makeFloat(program, 999)]), 999); > } > > okToTest = true; >diff --git a/Tools/WebGPUShadingLanguageRI/Texture.js b/Tools/WebGPUShadingLanguageRI/Texture.js >new file mode 100644 >index 0000000000000000000000000000000000000000..9d6e05ac8178789a65f300b1000861608245df8b >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/Texture.js >@@ -0,0 +1,534 @@ >+/* >+ * 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"; >+ >+class Texture { >+ constructor(dimension, width, height, depth, levelCount, layerCount, innerType, data) >+ { >+ this._dimension = dimension; >+ this._width = width; >+ this._height = height; >+ this._depth = depth; >+ this._levelCount = levelCount; >+ this._layerCount = layerCount; >+ this._innerType = innerType; >+ this._data = data; >+ } >+ >+ get dimension() { return this._dimension; } >+ get width() { return this._width; } >+ get height() { return this._height; } >+ get depth() { return this._depth; } >+ get levelCount() { return this._levelCount; } >+ get layerCount() { return this._layerCount; } >+ get innerType() { return this._innerType; } >+ get data() { return this._data; } >+ >+ elementChecked(layer, level, k, j, i) >+ { >+ if (layer < 0 || layer >= this.layerCount >+ || level < 0 || level >= this.levelCount >+ || k < 0 || k >= this.depth >+ || j < 0 || j >= this.height >+ || i < 0 || i >= this.width) >+ return undefined; >+ return this.element(layer, level, k, j, i); >+ } >+ >+ setElementChecked(layer, level, k, j, i, value) >+ { >+ if (layer < 0 || layer >= this.layerCount >+ || level < 0 || level >= this.levelCount >+ || k < 0 || k >= this.depth >+ || j < 0 || j >= this.height >+ || i < 0 || i >= this.width) >+ return false; >+ this.setElement(layer, level, k, j, i, value); >+ return true; >+ } >+} >+ >+class Texture1D extends Texture { >+ constructor(innerType, data) >+ { >+ // "data" is an array of mipmaps. >+ // The first mipmap is an array of elements. >+ // Each element may be a scalar or an array of 2-4 scalars. >+ // The width must be a power-of-two. >+ // Each mipmap is half-size of the previous size. >+ >+ let dimension = 1; >+ let width = data[0].length; >+ let height = 1; >+ let depth = 1; >+ let levelCount = data.length; >+ let layerCount = 1; >+ super(dimension, width, height, depth, levelCount, layerCount, innerType, data); >+ } >+ >+ widthAtLevel(level) >+ { >+ return this.data[level].length; >+ } >+ >+ heightAtLevel(level) >+ { >+ return 1; >+ } >+ >+ depthAtLevel(level) >+ { >+ return 1; >+ } >+ >+ element(layer, level, k, j, i) >+ { >+ return this.data[level][i]; >+ } >+ >+ setElement(layer, level, k, j, i, value) >+ { >+ this.data[level][i] = value; >+ } >+} >+ >+class Texture1DArray extends Texture { >+ constructor(innerType, data) >+ { >+ // "data" is an array of 1D textures. >+ // All textures must have the same width and number of mipmaps. >+ >+ let dimension = 1; >+ let width = data[0][0].length; >+ let height = 1; >+ let depth = 1; >+ let levelCount = data[0].length; >+ let layerCount = data.length; >+ super(dimension, width, height, depth, levelCount, layerCount, innerType, data); >+ } >+ >+ widthAtLevel(level) >+ { >+ return this.data[0][level].length; >+ } >+ >+ heightAtLevel(level) >+ { >+ return 1; >+ } >+ >+ depthAtLevel(level) >+ { >+ return 1; >+ } >+ >+ element(layer, level, k, j, i) >+ { >+ return this.data[layer][level][i]; >+ } >+ >+ setElement(layer, level, k, j, i, value) >+ { >+ this.data[layer][level][i] = value; >+ } >+} >+ >+class Texture2D extends Texture { >+ constructor(innerType, data) >+ { >+ // "data" is an array of mipmaps. >+ // The first mipmap is a rectangular array of rows, where each row is an array of elements. >+ // Each element may be a scalar or an array of 2-4 scalars. >+ // The width and height must be powers-of-two. >+ // Each mipmap is half-width and half-height of the previous size. >+ >+ let dimension = 2; >+ let width = data[0][0].length; >+ let height = data[0].length; >+ let depth = 1; >+ let levelCount = data.length; >+ let layerCount = 1; >+ super(dimension, width, height, depth, levelCount, layerCount, innerType, data); >+ } >+ >+ widthAtLevel(level) >+ { >+ return this.data[level][0].length; >+ } >+ >+ heightAtLevel(level) >+ { >+ return this.data[level].length; >+ } >+ >+ depthAtLevel(level) >+ { >+ return 1; >+ } >+ >+ element(layer, level, k, j, i) >+ { >+ return this.data[level][j][i]; >+ } >+ >+ setElement(layer, level, k, j, i, value) >+ { >+ this.data[level][j][i] = value; >+ } >+} >+ >+class Texture2DArray extends Texture { >+ constructor(innerType, data) >+ { >+ // "data" is an array of 2D textures. >+ // All textures must have the same width, height and number of mipmaps. >+ >+ let dimension = 2; >+ let width = data[0][0][0].length; >+ let height = data[0][0].length; >+ let depth = 1; >+ let levelCount = data[0].length; >+ let layerCount = data.length; >+ super(dimension, width, height, depth, levelCount, layerCount, innerType, data); >+ } >+ >+ widthAtLevel(level) >+ { >+ return this.data[0][level][0].length; >+ } >+ >+ heightAtLevel(level) >+ { >+ return this.data[0][level].length; >+ } >+ >+ depthAtLevel(level) >+ { >+ return 1; >+ } >+ >+ element(layer, level, k, j, i) >+ { >+ return this.data[layer][level][j][i]; >+ } >+ >+ setElement(layer, level, k, j, i, value) >+ { >+ this.data[layer][level][j][i] = value; >+ } >+} >+ >+class Texture3D extends Texture { >+ constructor(innerType, data) >+ { >+ // "data" is an array of mipmaps. >+ // The first mipmap is an array of depth slices, each depth slice is an array of rows, and each row is an array of elements. >+ // Each element may be a scalar or an array of 2-4 scalars. >+ // The width, height, and depth must be powers-of-two. >+ // Each mipmap is half-width, half-height, and half-depth of the previous size. >+ >+ let dimension = 3; >+ let width = data[0][0][0].length; >+ let height = data[0][0].length; >+ let depth = data[0].length; >+ let levelCount = data.length; >+ let layerCount = 1; >+ super(dimension, width, height, depth, levelCount, layerCount, innerType, data); >+ } >+ >+ widthAtLevel(level) >+ { >+ return this.data[level][0][0].length; >+ } >+ >+ heightAtLevel(level) >+ { >+ return this.data[level][0].length; >+ } >+ >+ depthAtLevel(level) >+ { >+ return this.data[level].length; >+ } >+ >+ element(layer, level, k, j, i) >+ { >+ return this.data[level][k][j][i]; >+ } >+ >+ setElement(layer, level, k, j, i, value) >+ { >+ this.data[level][k][j][i] = value; >+ } >+} >+ >+class TextureCube extends Texture { >+ constructor(innerType, data) >+ { >+ // "data" is an array of 6 2D textures. >+ // All textures must have the same width, height, depth, and number of mipmaps. >+ >+ let dimension = 2; >+ let width = data[0][0][0].length; >+ let height = data[0][0].length; >+ let depth = 1; >+ let levelCount = data[0].length; >+ let layerCount = data.length; >+ super(dimension, width, height, depth, levelCount, layerCount, innerType, data); >+ } >+ >+ widthAtLevel(level) >+ { >+ return this.data[0][level][0].length; >+ } >+ >+ heightAtLevel(level) >+ { >+ return this.data[0][level].length; >+ } >+ >+ depthAtLevel(level) >+ { >+ return 1; >+ } >+ >+ element(layer, level, k, j, i) >+ { >+ return this.data[layer][level][j][i]; >+ } >+ >+ setElement(layer, level, k, j, i, value) >+ { >+ this.data[layer][level][j][i] = value; >+ } >+} >+ >+class Texture1DRW extends Texture { >+ constructor(innerType, data) >+ { >+ // "data" is an array of elements. >+ // Each element may be a scalar or an array of 2-4 scalars. >+ // The width must be a power-of-two. >+ >+ let dimension = 1; >+ let width = data.length; >+ let height = 1; >+ let depth = 1; >+ let levelCount = 1; >+ let layerCount = 1; >+ super(dimension, width, height, depth, levelCount, layerCount, innerType, data); >+ } >+ >+ widthAtLevel(level) >+ { >+ return this.data.length; >+ } >+ >+ heightAtLevel(level) >+ { >+ return 1; >+ } >+ >+ depthAtLevel(level) >+ { >+ return 1; >+ } >+ >+ element(layer, level, k, j, i) >+ { >+ return this.data[i]; >+ } >+ >+ setElement(layer, level, k, j, i, value) >+ { >+ this.data[i] = value; >+ } >+} >+ >+class Texture1DArrayRW extends Texture { >+ constructor(innerType, data) >+ { >+ // "data" is an array of 1D RW textures. >+ // All textures must have the same size. >+ >+ let dimension = 1; >+ let width = data[0].length; >+ let height = 1; >+ let depth = 1; >+ let levelCount = 1; >+ let layerCount = data.length; >+ super(dimension, width, height, depth, levelCount, layerCount, innerType, data); >+ } >+ >+ widthAtLevel(level) >+ { >+ return this.data[0].length; >+ } >+ >+ heightAtLevel(level) >+ { >+ return 1; >+ } >+ >+ depthAtLevel(level) >+ { >+ return 1; >+ } >+ >+ element(layer, level, k, j, i) >+ { >+ return this.data[layer][i]; >+ } >+ >+ setElement(layer, level, k, j, i, value) >+ { >+ this.data[layer][i] = value; >+ } >+} >+ >+class Texture2DRW extends Texture { >+ constructor(innerType, data) >+ { >+ // "data" is a rectangular array of rows, where each row is an array of elements. >+ // Each element may be a scalar or an array of 2-4 scalars. >+ // The width and height must be powers-of-two. >+ >+ let dimension = 2; >+ let width = data[0].length; >+ let height = data.length; >+ let depth = 1; >+ let levelCount = 1; >+ let layerCount = 1; >+ super(dimension, width, height, depth, levelCount, layerCount, innerType, data); >+ } >+ >+ widthAtLevel(level) >+ { >+ return this.data[0].length; >+ } >+ >+ heightAtLevel(level) >+ { >+ return this.data.length; >+ } >+ >+ depthAtLevel(level) >+ { >+ return 1; >+ } >+ >+ element(layer, level, k, j, i) >+ { >+ return this.data[j][i]; >+ } >+ >+ setElement(layer, level, k, j, i, value) >+ { >+ this.data[j][i] = value; >+ } >+} >+ >+class Texture2DArrayRW extends Texture { >+ constructor(innerType, data) >+ { >+ // "data" is an array of 2D RW textures. >+ // All textures must have the same width and height. >+ >+ let dimension = 2; >+ let width = data[0][0].length; >+ let height = data[0].length; >+ let depth = 1; >+ let levelCount = 1; >+ let layerCount = data.length; >+ super(dimension, width, height, depth, levelCount, layerCount, innerType, data); >+ } >+ >+ widthAtLevel(level) >+ { >+ return this.data[0][0].length; >+ } >+ >+ heightAtLevel(level) >+ { >+ return this.data[0].length; >+ } >+ >+ depthAtLevel(level) >+ { >+ return 1; >+ } >+ >+ element(layer, level, k, j, i) >+ { >+ return this.data[layer][j][i]; >+ } >+ >+ setElement(layer, level, k, j, i, value) >+ { >+ this.data[layer][j][i] = value; >+ } >+} >+ >+class Texture3DRW extends Texture { >+ constructor(innerType, data) >+ { >+ // "data" is an array of depth slices, each depth slice is an array of rows, and each row is an array of elements. >+ // Each element may be a scalar or an array of 2-4 scalars. >+ // The width, height, and depth must be powers-of-two. >+ >+ let dimension = 3; >+ let width = data[0][0].length; >+ let height = data[0].length; >+ let depth = data.length; >+ let levelCount = 1; >+ let layerCount = 1; >+ super(dimension, width, height, depth, levelCount, layerCount, innerType, data); >+ } >+ >+ widthAtLevel(level) >+ { >+ return this.data[0][0].length; >+ } >+ >+ heightAtLevel(level) >+ { >+ return this.data[0].length; >+ } >+ >+ depthAtLevel(level) >+ { >+ return this.data.length; >+ } >+ >+ element(layer, level, k, j, i) >+ { >+ return this.data[k][j][i]; >+ } >+ >+ setElement(layer, level, k, j, i, value) >+ { >+ this.data[k][j][i] = value; >+ } >+} >diff --git a/Tools/WebGPUShadingLanguageRI/TextureOperations.js b/Tools/WebGPUShadingLanguageRI/TextureOperations.js >new file mode 100644 >index 0000000000000000000000000000000000000000..6d8a8b3cf7aa00263234539e4f06429c4c2cf7f7 >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/TextureOperations.js >@@ -0,0 +1,538 @@ >+/* >+ * 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 depthCompareOperation(dref, d, compareFunction) >+{ >+ // Vulkan 1.1.83 section 15.3.4 >+ switch (compareFunction) { >+ case "never": >+ return 0; >+ case "less": >+ return dref < d ? 1 : 0; >+ case "equal": >+ return dref == d ? 1 : 0; >+ case "lessEqual": >+ return dref <= d ? 1 : 0; >+ case "greater": >+ return dref > d ? 1 : 0; >+ case "notEqual": >+ return dref != d ? 1 : 0; >+ case "greaterEqual": >+ return dref >= d ? 1 : 0; >+ case "always": >+ return 1; >+ default: >+ throw new Error("Unknown depth comparison function"); >+ } >+} >+ >+function conversionToRGBA(value) >+{ >+ // Vulkan 1.1.83 section 15.3.5 >+ if (value instanceof Array) { >+ var result = []; >+ for (let i = 0; i < value.length; ++i) >+ result.push(value[i]); >+ while (result.length != 4) >+ result.push(result.length == 3 ? 1 : 0); >+ return result; >+ } else >+ return [value, 0, 0, 1]; >+} >+ >+//For explicit LOD image instructions, if the optional SPIR-V operand Grad is provided, then the operand values are used for the derivatives. The number of components present in each derivative for a given image dimensionality matches the number of partial derivatives computed above. >+//If the optional SPIR-V operand Lod is provided, then derivatives are set to zero, the cube map derivative transformation is skipped, and the scale factor operation is skipped. Instead, the floating point scalar coordinate is directly assigned to λbase as described in Level-of-Detail Operation. >+function implicitDerivative() >+{ >+ // Vulkan 1.1.83 section 15.5 >+ return 0; >+} >+ >+function projectionOperation(s, t, r, dref, q) >+{ >+ // Vulkan 1.1.83 section 15.6.1 >+ return [s / q, t / q, r / q, dref / q]; >+} >+ >+function cubeMapFaceSelection(s, t, r, partialRxWithRespectToX, partialRxWithRespectToY, partialRyWithRespectToX, partialRyWithRespectToY, partialRzWithRespectToX, partialRzWithRespectToY) >+{ >+ // Vulkan 1.1.83 section 15.6.4 >+ let rx = s; >+ let ry = t; >+ let rz = r; >+ let winner = 0; >+ if (Math.abs(rz) >= Math.abs(ry) && Math.abs(rz) >= Math.abs(rx)) >+ winner = 2; >+ else if (Math.abs(ry) >= Math.abs(rx) && Math.abs(ry) >= Math.abs(rz)) >+ winner = 1; >+ >+ let layerNumber; >+ let sc; >+ let tc; >+ let rc; >+ let partialScWithRespectToX; >+ let partialScWithRespectToY; >+ let partialTcWithRespectToX; >+ let partialTcWithRespectToY; >+ let partialRcWithRespectToX; >+ let partialRcWithRespectToY; >+ if (winner == 0 && rx >= 0) { >+ layerNumber = 0; >+ sc = -rz; >+ tc = -ry; >+ rc = rx; >+ partialScWithRespectToX = -partialRzWithRespectToX; >+ partialScWithRespectToY = -partialRzWithRespectToY; >+ partialTcWithRespectToX = -partialRyWithRespectToX; >+ partialTcWithRespectToY = -partialRyWithRespectToY; >+ partialRcWithRespectToX = partialRxWithRespectToX; >+ partialRcWithRespectToY = partialRxWithRespectToY; >+ } else if (winner == 0) { >+ layerNumber = 1; >+ sc = rz; >+ tc = -ry; >+ rc = rx; >+ partialScWithRespectToX = partialRzWithRespectToX; >+ partialScWithRespectToY = partialRzWithRespectToY; >+ partialTcWithRespectToX = -partialRyWithRespectToX; >+ partialTcWithRespectToY = -partialRyWithRespectToY; >+ partialRcWithRespectToX = -partialRxWithRespectToX; >+ partialRcWithRespectToY = -partialRxWithRespectToY; >+ } else if (winner == 1 && ry >= 0) { >+ layerNumber = 2; >+ sc = rx; >+ tc = -rz; >+ rc = ry; >+ partialScWithRespectToX = partialRxWithRespectToX; >+ partialScWithRespectToY = partialRxWithRespectToY; >+ partialTcWithRespectToX = partialRzWithRespectToX; >+ partialTcWithRespectToY = partialRzWithRespectToY; >+ partialRcWithRespectToX = partialRyWithRespectToX; >+ partialRcWithRespectToY = partialRyWithRespectToY; >+ } else if (winner == 1) { >+ layerNumber = 3; >+ sc = rx; >+ tc = -rz; >+ rc = ry; >+ partialScWithRespectToX = partialRxWithRespectToX; >+ partialScWithRespectToY = partialRxWithRespectToY; >+ partialTcWithRespectToX = -partialRzWithRespectToX; >+ partialTcWithRespectToY = -partialRzWithRespectToY; >+ partialRcWithRespectToX = -partialRyWithRespectToX; >+ partialRcWithRespectToY = -partialRyWithRespectToY; >+ } else if (winner == 2 && rz >= 0) { >+ layerNumber = 4; >+ sc = rx; >+ tc = -ry; >+ rc = rz; >+ partialScWithRespectToX = partialRxWithRespectToX; >+ partialScWithRespectToY = partialRxWithRespectToY; >+ partialTcWithRespectToX = -partialRyWithRespectToX; >+ partialTcWithRespectToY = -partialRyWithRespectToY; >+ partialRcWithRespectToX = partialRzWithRespectToX; >+ partialRcWithRespectToY = partialRzWithRespectToY; >+ } else { >+ layerNumber = 5; >+ sc = -rx; >+ tc = -ry; >+ rc = rz; >+ partialScWithRespectToX = -partialRxWithRespectToX; >+ partialScWithRespectToY = -partialRxWithRespectToY; >+ partialTcWithRespectToX = -partialRyWithRespectToX; >+ partialTcWithRespectToY = -partialRyWithRespectToY; >+ partialRcWithRespectToX = -partialRzWithRespectToX; >+ partialRcWithRespectToY = -partialRzWithRespectToY; >+ } >+ return [layerNumber, sc, tc, rc, partialScWithRespectToX, partialScWithRespectToY, partialTcWithRespectToX, partialTcWithRespectToY, partialRcWithRespectToX, partialRcWithRespectToY] >+} >+ >+function cubeMapCoordinateTransformation(sc, rc) >+{ >+ // Vulkan 1.1.83 section 15.6.5 >+ let sFace = (1 / 2) * sc / Math.abs(rc) + (1 / 2); >+ let tFace = (1 / 2) * tc / Math.abs(rc) + (1 / 2); >+ return [sFace, tFace]; >+} >+ >+function cubeMapDerivativeTransformation(sc, tc, rc, partialScWithRespectToX, partialScWithRespectToY, partialTcWithRespectToX, partialTcWithRespectToY, partialRcWithRespectToX, partialRcWithRespectToY) >+{ >+ // Vulkan 1.1.83 section 15.6.6 >+ let partialSFaceWithRespectToX = (1 / 2) * ((Math.abs(rc) * partialScWithRespectToX - sc * partialRcWithRespectToX) / Math.pow(rc, 2)); >+ let partialSFaceWithRespectToY = (1 / 2) * ((Math.abs(rc) * partialScWithRespectToY - sc * partialRcWithRespectToY) / Math.pow(rc, 2)); >+ let partialTFaceWithRespectToX = (1 / 2) * ((Math.abs(rc) * partialTcWithRespectToX - tc * partialRcWithRespectToX) / Math.pow(rc, 2)); >+ let partialTFaceWithRespectToY = (1 / 2) * ((Math.abs(rc) * partialTcWithRespectToY - tc * partialRcWithRespectToY) / Math.pow(rc, 2)); >+ return [partialSFaceWithRespectToX, partialSFaceWithRespectToY, partialTFaceWithRespectToX, partialTFaceWithRespectToY]; >+} >+ >+function scaleFactorOperation(deviceMaxAnisotropy, width, height, depth, samplerMaxAnisotropy, partialSWithRespectToX, partialTWithRespectToX, partialRWithRespectToX, partialSWithRespectToY, partialTWithRespectToY, partialRWithRespectToY) >+{ >+ // Vulkan 1.1.83 section 15.6.7 >+ let mux = Math.abs(partialSWithRespectToX) * width; >+ let mvx = Math.abs(partialTWithRespectToX) * height; >+ let mwx = Math.abs(partialRWithRespectToX) * depth; >+ let muy = Math.abs(partialSWithRespectToY) * width; >+ let mvy = Math.abs(partialTWithRespectToY) * height; >+ let mwy = Math.abs(partialRWithRespectToY) * depth; >+ >+ let fx = Math.sqrt(2) * (mux + mvx + mwx); >+ let fy = Math.sqrt(2) * (muy + mvy + mwy); >+ >+ let rhoX = fx; >+ let rhoY = fy; >+ let rhoMax = Math.max(rhoX, rhoY); >+ let rhoMin = Math.min(rhoX, rhoY); >+ >+ let maxAniso = Math.min(samplerMaxAnisotropy, deviceMaxAnisotropy); >+ >+ let eta; >+ if (rhoMax == 0 && rhoMin == 0) >+ eta = 1; >+ else if (rhoMin == 0) >+ eta = maxAniso; >+ else >+ eta = Math.min(rhoMax / rhoMin, maxAniso); >+ >+ let N = Math.ceil(eta); >+ return [rhoMax, rhoMin, eta, N]; >+} >+ >+function levelOfDetailOperation(deviceMaxSamplerLodBias, lodFromFunctionOperand, lodMinFromFunctionOperand, biasFromFunctionOperand, samplerBias, samplerLodMin, samplerLoadMax, rhoMax, eta) >+{ >+ // Vulkan 1.1.83 section 15.6.7 >+ let lambdaBase = lodFromFunctionOperand != undefined ? lodFromFunctionOperand : Math.log2(rhoMax / eta); >+ let lambdaPrime = lambdaBase + Math.min(Math.max(samplerBias + biasFromFunctionOperand, -deviceMaxSamplerLodBias), deviceMaxSamplerLodBias); >+ let lodMin = Math.max(samplerLodMin, lodMinFromFunctionOperand); >+ let lodMax = samplerLoadMax; >+ let lambda; >+ if (lambdaPrime > lodMax) >+ lambda = lodMax; >+ else if (lodMin <= lambdaPrime && lambdaPrime <= lodMax) >+ lambda = lambdaPrime; >+ else if (lambdaPrime < lodMin) >+ lambda = lodMin; >+ else >+ throw new Error("lodMin >= lodMax"); >+ return lambda; >+} >+ >+function imageLevelSelection(baseMipLevel, levelCount, mipmapMode, lambda) >+{ >+ // Vulkan 1.1.83 section 15.6.7 >+ function nearest(dPrime) >+ { >+ return Math.ceil(dPrime + 0.5) - 1; >+ } >+ >+ let q = levelCount - 1; >+ let dPrime = baseMipLevel + Math.min(Math.max(lambda, 0), q); >+ let dl; >+ if (mipmapMode == "nearest") >+ dl = nearest(dPrime); >+ else >+ dl = dPrime; >+ if (mipmapMode == "nearest") >+ return dl; >+ else { >+ let dHi = Math.floor(dl); >+ let dLow = Math.min(dHi + 1, q); >+ let delta = dl - dHi; >+ return [dHi, dLow, delta]; >+ } >+} >+ >+function strqaToUVWATransformation(s, t, r, width, height, depth) >+{ >+ // Vulkan 1.1.83 section 15.6.8 >+ let u = s * width; >+ let v = t * height; >+ let w = r * depth; >+ return [u, v, w]; >+} >+ >+function uvwaToIJKLNTransformationAndArrayLayerSelection(layerCount, baseArrayLayer, filter, u, v, w, a, deltaI, deltaJ, deltaK) >+{ >+ // Vulkan 1.1.83 section 15.7.1 >+ function rne(a) >+ { >+ return Math.floor(a + 0.5); >+ } >+ let l = Math.min(Math.max(rne(a), 0), layerCount - 1) + baseArrayLayer; >+ let i; >+ let j; >+ let k; >+ if (filter == "nearest") { >+ i = Math.floor(u); >+ j = Math.floor(v); >+ k = Math.floor(w); >+ >+ i += deltaI; >+ j += deltaJ; >+ k += deltaK; >+ >+ return [i, j, k, l]; >+ } else { >+ if (filter != "linear") >+ throw new Error("Unknown filter"); >+ let i0 = Math.floor(u - 0.5); >+ let i1 = i0 + 1; >+ let j0 = Math.floor(v - 0.5); >+ let j1 = j0 + 1; >+ let k0 = Math.floor(w - 0.5); >+ let k1 = k0 + 1; >+ let alpha = (u - 0.5) - i0; >+ let beta = (v - 0.5) - j0; >+ let gamma = (w - 0.5) - k0; >+ >+ i0 += deltaI; >+ i1 += deltaI; >+ j0 += deltaJ; >+ j1 += deltaJ; >+ k0 += deltaK; >+ k1 += deltaK; >+ >+ return [i0, i1, j0, j1, k0, k1, l, alpha, beta, gamma]; >+ } >+} >+ >+function integerTexelCoordinateOperations(baseMipLevel, levelCount, levelBase, lodFromFunctionOperand) >+{ >+ // Vulkan 1.1.83 section 15.8 >+ let d = levelBase + lodFromFunctionOperand; >+ if (d < baseMipLevel || d >= baseMipLevel + levelCount) >+ throw new Error("Selected level does not lie inside the image"); >+ return d; >+} >+ >+function wrappingOperation(width, height, depth, addressModeU, addressModeV, addressModeW, i, j, k) >+{ >+ // Vulkan 1.1.83 section 15.9.1 >+ // FIXME: Implement cube map handling >+ function transform(addressMode, size, i) >+ { >+ function mirror(n) { >+ if (n >= 0) >+ return n; >+ else >+ return -(1 + n); >+ } >+ switch (addressMode) { >+ case "clampToEdge": >+ return Math.min(Math.max(i, 0), size - 1); >+ case "repeat": >+ return i % size; >+ case "mirrorRepeat": >+ return (size - 1) - mirror((i % (2 * size)) - size); >+ case "clampToBorderColor": >+ return Math.min(Math.max(i, -1), size); >+ default: >+ throw new Error("Unknown address mode"); >+ } >+ } >+ return [transform(addressModeU, width, i), transform(addressModeV, height, j), transform(addressModeW, depth, k)]; >+} >+ >+function texelGathering() >+{ >+ // Vulkan 1.1.83 section 15.9.2 >+ // FIXME: Implement this >+ /*let tauR = ; >+ let tauG = ; >+ let tauB = ; >+ let tauA = ;*/ >+} >+ >+function texelFiltering( >+ deviceMaxAnisotropy, >+ deviceMaxSamplerLodBias, >+ baseMipLevel, >+ baseArrayLayer, >+ texture, >+ sampler, >+ samplerBias, >+ s, t, r, a, >+ deltaI, deltaJ, deltaK, >+ lodFromFunctionOperand, >+ lodMinFromFunctionOperand, >+ biasFromFunctionOperand, >+ ddx, ddy) >+{ >+ // Vulkan 1.1.83 section 15.9.3 >+ >+ // The spec uses different names than WebGPU does. >+ let addressModeU = sampler.rAddressMode; >+ let addressModeV = sampler.sAddressMode; >+ let addressModeW = sampler.tAddressMode; >+ >+ let filter; >+ if (lambda <= 0) >+ filter = sampler.magFilter; >+ else >+ filter = sampler.minFilter; >+ >+ function computeTau(level) >+ { >+ function reduce(...values) >+ { >+ if (values.length % 2 != 0) >+ throw new Error("Don't have a weight corresponding to each value"); >+ let sum = 0; >+ // FIXME: These arguments need to be averaged component-wise. >+ for (let i = 0; i < values.length / 2; ++i) >+ sum += values[2 * i] * values[2 * i + 1]; >+ return sum; >+ } >+ >+ function accessColor(width, height, depth, l, i, j, k) >+ { >+ function shouldBeBorder(value, max) >+ { >+ if (value < -1 || value > max) >+ throw new Error("Out-of-bounds texture read"); >+ return value == -1 || value == max; >+ } >+ >+ let [wrappedI, wrappedJ, wrappedK] = wrappingOperation(width, height, depth, addressModeU, addressModeV, addressModeW, i, j, k) >+ if (shouldBeBorder(wrappedI, width) || shouldBeBorder(wrappedJ, height) || shouldBeBorder(wrappedK, depth)) >+ return sampler.borderColor(texture.innerType); >+ else >+ return texture.element(l, level, k, j, i); >+ } >+ >+ let [u, v, w] = strqaToUVWATransformation(s, t, r, texture.widthAtLevel(level), texture.heightAtLevel(level), texture.depthAtLevel(level)); >+ if (filter == "nearest") { >+ let [i, j, k, l] = uvwaToIJKLNTransformationAndArrayLayerSelection(texture.layerCount, baseArrayLayer, filter, u, v, w, a, deltaI, deltaJ, deltaK); >+ return accessColor(width, height, depth, l, i, j, k); >+ } else { >+ if (mipmapMode != "linear") >+ throw new Error("Unknown filter"); >+ [i0, i1, j0, j1, k0, k1, l, alpha, beta, gamma] = uvwaToIJKLNTransformationAndArrayLayerSelection(texture.layerCount, baseArrayLayer, filter, u, v, w, a, deltaI, deltaJ, deltaK); >+ let color000 = accessColor(width, height, depth, l, i0, j0, k0); >+ let color100 = accessColor(width, height, depth, l, i1, j0, k0); >+ let color010 = accessColor(width, height, depth, l, i0, j1, k0); >+ let color110 = accessColor(width, height, depth, l, i1, j1, k0); >+ let color001 = accessColor(width, height, depth, l, i0, j0, k1); >+ let color101 = accessColor(width, height, depth, l, i1, j0, k1); >+ let color011 = accessColor(width, height, depth, l, i0, j1, k1); >+ let color111 = accessColor(width, height, depth, l, i1, j1, k1); >+ switch (texture.dimension) { >+ case 1: >+ let color0 = color011; >+ let color1 = color111; >+ return reduce(1 - alpha, color0, alpha, color1); >+ case 2: >+ let color00 = color001; >+ let color10 = color101; >+ let color01 = color011; >+ let color11 = color111; >+ return reduce((1 - alpha) * (1 - beta), color00, alpha * (1 - beta), color10, (1 - alpha) * beta, color01, alpha * beta, color11); >+ case 3: >+ return reduce( >+ (1 - alpha) * (1 - beta) * (1 - gamma), color000, >+ alpha * (1 - beta) * (1 - gamma), color100, >+ (1 - alpha) * beta * (1 - gamma), color010, >+ alpha * beta * (1 - gamma), color110, >+ (1 - alpha) * (1 - beta) * gamma, color001, >+ alpha * (1 - beta) * gamma, color101, >+ (1 - alpha) * beta * gamma, color011, >+ alpha * beta * gamma, color111); >+ default: >+ throw new Error("Unknown dimension"); >+ } >+ } >+ } >+ >+ // FIXME: Make this work with cubemaps >+ let partialSWithRespectToX = 0; >+ let partialTWithRespectToX = 0; >+ let partialRWithRespectToX = 0; >+ if (ddx != undefined) { >+ partialSWithRespectToX = ddx[0]; >+ partialTWithRespectToX = ddx[1]; >+ partialRWithRespectToX = ddx[2]; >+ } >+ let partialSWithRespectToY = 0; >+ let partialTWithRespectToY = 0; >+ let partialRWithRespectToY = 0; >+ if (ddy != undefined) { >+ partialSWithRespectToY = ddy[0]; >+ partialTWithRespectToY = ddy[1]; >+ partialRWithRespectToY = ddy[2]; >+ } >+ let [rhoMax, rhoMin, eta, N] = scaleFactorOperation(deviceMaxAnisotropy, texture.width, texture.height, texture.depth, samplerMaxAnisotropy, partialSWithRespectToX, partialTWithRespectToX, partialRWithRespectToX, partialSWithRespectToY, partialTWithRespectToY, partialRWithRespectToY); >+ let lambda = levelOfDetailOperation(deviceMaxSamplerLodBias, lodFromFunctionOperand, lodMinFromFunctionOperand, biasFromFunctionOperand, samplerBias, samplerLodMin, samplerLoadMax, rhoMax, eta); >+ >+ if (mipmapMode == "nearest") { >+ let imageLevel = imageLevelSelection(baseMipLevel, texture.levelCount, mipmapMode, lambda); >+ return computeTau(imageLevel); >+ } else { >+ if (mipmapMode != "linear") >+ throw new Error("Unknown filter"); >+ let [dHi, dLow, delta] = imageLevelSelection(baseMipLevel, texture.levelCount, mipmapMode, lambda); >+ return reduce(1 - delta, computeTau(dHi), delta, computeTau(dLo)); >+ } >+} >+ >+function sampleTexture(texture, sampler, location, delta, biasFromFunctionOperand, ddx, ddy, lodFromFunctionOperand, dref) >+{ >+ let s = location[0]; >+ let t = location[1]; >+ let r = location[2]; >+ let q = location[3]; >+ let a = location[4]; >+ >+ let deltaI = undefined; >+ let deltaJ = undefined; >+ let deltaK = undefined; >+ if (delta != undefined) { >+ deltaI = delta[0]; >+ deltaJ = delta[1]; >+ deltaK = delta[2]; >+ } >+ >+ [s, t, r, dref] = projectionOperation(s, t, r, dref, q); >+ let result = texelFiltering( >+ Number.MAX_VALUE, >+ Number.MAX_VALUE, >+ 0, >+ 0, >+ texture, >+ sampler, >+ 0, >+ s, t, r, a, >+ deltaI, deltaJ, deltaK, >+ lodFromFunctionOperand, >+ 0, >+ biasFromFunctionOperand, >+ ddx, ddy); >+ if (dref != undefined) { >+ if (result instanceof Array) >+ throw new Error("Depth comparison not supported on multichannel textures"); >+ result = depthCompareOperation(dref, result, sampler.compareFunction); >+ } >+ return result; >+ // FIXME: Figure out what to do with anisotropy >+ // FIXME: Figure out how to do multisampling. >+} >diff --git a/Tools/WebGPUShadingLanguageRI/index.html b/Tools/WebGPUShadingLanguageRI/index.html >index 65a86411b3e770b557b41acc7e414def42403013..338ee9c9b938b5482b888e4e924dccddbe7fb2cd 100644 >--- a/Tools/WebGPUShadingLanguageRI/index.html >+++ b/Tools/WebGPUShadingLanguageRI/index.html >@@ -127,6 +127,8 @@ > <script src="SynthesizeCopyConstructorOperator.js"></script> > <script src="SynthesizeDefaultConstructorOperator.js"></script> > <script src="TernaryExpression.js"></script> >+<script src="Texture.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