From 19c7c371aaef9dc537f6a6ed8cbfd77355f219ff Mon Sep 17 00:00:00 2001 From: Tim Foley Date: Mon, 6 Nov 2017 14:05:32 -0800 Subject: Remove `__intrinsic_op` from many decls This attribute used to be how we marked ops for special handling in emission, but now it is being used to mark ops that map to single instructions. Either way, we have a bunch of intrinsic functions that need to get lowered in a more traditional fashion for HLSL, and the intrinsics are getting in the way. Subsequent changes will fix up issues created by this removal. A few cases were left unchanged, either because the ops really do map to single instructions, or because there is some special-case support attached to those operations that would be tricky to replace right now. --- source/slang/core.meta.slang | 27 +- source/slang/core.meta.slang.h | 27 +- source/slang/hlsl.meta.slang | 760 ++++++++++++++++++++--------------------- source/slang/hlsl.meta.slang.h | 760 ++++++++++++++++++++--------------------- 4 files changed, 750 insertions(+), 824 deletions(-) (limited to 'source') diff --git a/source/slang/core.meta.slang b/source/slang/core.meta.slang index 8accc83a4..f36b53227 100644 --- a/source/slang/core.meta.slang +++ b/source/slang/core.meta.slang @@ -444,13 +444,6 @@ for (int tt = 0; tt < kBaseTextureTypeCount; ++tt) sb << ")\")\n"; - - - // TIM: Making `GetDimensions` *not* be marked as - // an intrinsic, just so we can see how defining - // things as `extern` functions would work. -// sb << "__intrinsic_op\n"; - } char const* t = isFloat ? "out float " : "out uint "; @@ -524,7 +517,6 @@ for (int tt = 0; tt < kBaseTextureTypeCount; ++tt) { sb << "__target_intrinsic(glsl, \"texelFetch($$P, ($0)." << kGLSLLoadCoordsSwizzle[loadCoordCount] << ", ($0)." << kGLSLLoadLODSwizzle[loadCoordCount] << ")\")\n"; } - sb << "__intrinsic_op\n"; sb << "T Load("; sb << "int" << loadCoordCount << " location"; if(isMultisample) @@ -541,7 +533,6 @@ for (int tt = 0; tt < kBaseTextureTypeCount; ++tt) { sb << "__target_intrinsic(glsl, \"texelFetch($$P, ($0)." << kGLSLLoadCoordsSwizzle[loadCoordCount] << ", ($0)." << kGLSLLoadLODSwizzle[loadCoordCount] << ", $1)\")\n"; } - sb << "__intrinsic_op\n"; sb << "T Load("; sb << "int" << loadCoordCount << " location"; if(isMultisample) @@ -569,7 +560,7 @@ for (int tt = 0; tt < kBaseTextureTypeCount; ++tt) // this should have both `get` and `set` accessors. // subscript operator - sb << "__intrinsic_op __subscript(uint"; + sb << "__subscript(uint"; if(kBaseTextureTypes[tt].coordCount + isArray > 1) { sb << kBaseTextureTypes[tt].coordCount + isArray; @@ -584,16 +575,14 @@ for (int tt = 0; tt < kBaseTextureTypeCount; ++tt) sb << "__target_intrinsic(glsl, \"texture($$p, $1)\")\n"; // TODO: only enable if IR is being used? - sb << "__intrinsic_op(sample)\n"; +// sb << "__intrinsic_op(sample)\n"; - sb << "__intrinsic_op\n"; sb << "T Sample(SamplerState s, "; sb << "float" << kBaseTextureTypes[tt].coordCount + isArray << " location);\n"; if( baseShape != TextureType::ShapeCube ) { sb << "__target_intrinsic(glsl, \"textureOffset($$p, $1, $2)\")\n"; - sb << "__intrinsic_op\n"; sb << "T Sample(SamplerState s, "; sb << "float" << kBaseTextureTypes[tt].coordCount + isArray << " location, "; sb << "int" << kBaseTextureTypes[tt].coordCount << " offset);\n"; @@ -618,14 +607,12 @@ for (int tt = 0; tt < kBaseTextureTypeCount; ++tt) // `SampleBias()` sb << "__target_intrinsic(glsl, \"texture($$p, $1, $2)\")\n"; - sb << "__intrinsic_op\n"; sb << "T SampleBias(SamplerState s, "; sb << "float" << kBaseTextureTypes[tt].coordCount + isArray << " location, float bias);\n"; if( baseShape != TextureType::ShapeCube ) { sb << "__target_intrinsic(glsl, \"textureOffset($$p, $1, $2, $3)\")\n"; - sb << "__intrinsic_op\n"; sb << "T SampleBias(SamplerState s, "; sb << "float" << kBaseTextureTypes[tt].coordCount + isArray << " location, float bias, "; sb << "int" << kBaseTextureTypes[tt].coordCount << " offset);\n"; @@ -678,7 +665,6 @@ for (int tt = 0; tt < kBaseTextureTypeCount; ++tt) sb << ", vec" << baseCoordCount << "(0.0)"; sb << ")\")\n"; } - sb << "__intrinsic_op\n"; sb << "T SampleCmpLevelZero(SamplerComparisonState s, "; sb << "float" << kBaseTextureTypes[tt].coordCount + isArray << " location, "; sb << "float compareValue"; @@ -706,7 +692,7 @@ for (int tt = 0; tt < kBaseTextureTypeCount; ++tt) sb << "__target_intrinsic(glsl, \"textureGrad($$p, $1, $2, $3)\")\n"; - sb << "__intrinsic_op(sampleGrad)\n"; +// sb << "__intrinsic_op(sampleGrad)\n"; sb << "T SampleGrad(SamplerState s, "; sb << "float" << kBaseTextureTypes[tt].coordCount + isArray << " location, "; sb << "float" << kBaseTextureTypes[tt].coordCount << " gradX, "; @@ -716,7 +702,7 @@ for (int tt = 0; tt < kBaseTextureTypeCount; ++tt) if( baseShape != TextureType::ShapeCube ) { sb << "__target_intrinsic(glsl, \"textureGradOffset($$p, $1, $2, $3, $4)\")\n"; - sb << "__intrinsic_op(sampleGrad)\n"; +// sb << "__intrinsic_op(sampleGrad)\n"; sb << "T SampleGrad(SamplerState s, "; sb << "float" << kBaseTextureTypes[tt].coordCount + isArray << " location, "; sb << "float" << kBaseTextureTypes[tt].coordCount << " gradX, "; @@ -727,7 +713,6 @@ for (int tt = 0; tt < kBaseTextureTypeCount; ++tt) // `SampleLevel` sb << "__target_intrinsic(glsl, \"textureLod($$p, $1, $2)\")\n"; - sb << "__intrinsic_op\n"; sb << "T SampleLevel(SamplerState s, "; sb << "float" << kBaseTextureTypes[tt].coordCount + isArray << " location, "; sb << "float level);\n"; @@ -735,7 +720,6 @@ for (int tt = 0; tt < kBaseTextureTypeCount; ++tt) if( baseShape != TextureType::ShapeCube ) { sb << "__target_intrinsic(glsl, \"textureLodOffset($$p, $1, $2, $3)\")\n"; - sb << "__intrinsic_op\n"; sb << "T SampleLevel(SamplerState s, "; sb << "float" << kBaseTextureTypes[tt].coordCount + isArray << " location, "; sb << "float level, "; @@ -803,13 +787,11 @@ for (int tt = 0; tt < kBaseTextureTypeCount; ++tt) EMIT_LINE_DIRECTIVE(); sb << "__target_intrinsic(glsl, \"textureGather($$p, $1, " << componentIndex << ")\")\n"; - sb << "__intrinsic_op\n"; sb << "vector Gather" << componentName << "(SamplerState s, "; sb << "float" << kBaseTextureTypes[tt].coordCount << " location);\n"; EMIT_LINE_DIRECTIVE(); sb << "__target_intrinsic(glsl, \"textureGatherOffset($$p, $1, $2, " << componentIndex << ")\")\n"; - sb << "__intrinsic_op\n"; sb << "vector Gather" << componentName << "(SamplerState s, "; sb << "float" << kBaseTextureTypes[tt].coordCount << " location, "; sb << "int" << kBaseTextureTypes[tt].coordCount << " offset);\n"; @@ -822,7 +804,6 @@ for (int tt = 0; tt < kBaseTextureTypeCount; ++tt) EMIT_LINE_DIRECTIVE(); sb << "__target_intrinsic(glsl, \"textureGatherOffsets($$p, $1, int" << kBaseTextureTypes[tt].coordCount << "[]($2, $3, $4, $5), " << componentIndex << ")\")\n"; - sb << "__intrinsic_op\n"; sb << "vector Gather" << componentName << "(SamplerState s, "; sb << "float" << kBaseTextureTypes[tt].coordCount << " location, "; sb << "int" << kBaseTextureTypes[tt].coordCount << " offset1, "; diff --git a/source/slang/core.meta.slang.h b/source/slang/core.meta.slang.h index 6b60d2896..1c0f28b26 100644 --- a/source/slang/core.meta.slang.h +++ b/source/slang/core.meta.slang.h @@ -447,13 +447,6 @@ for (int tt = 0; tt < kBaseTextureTypeCount; ++tt) sb << ")\")\n"; - - - // TIM: Making `GetDimensions` *not* be marked as - // an intrinsic, just so we can see how defining - // things as `extern` functions would work. -// sb << "__intrinsic_op\n"; - } char const* t = isFloat ? "out float " : "out uint "; @@ -527,7 +520,6 @@ for (int tt = 0; tt < kBaseTextureTypeCount; ++tt) { sb << "__target_intrinsic(glsl, \"texelFetch($P, ($0)." << kGLSLLoadCoordsSwizzle[loadCoordCount] << ", ($0)." << kGLSLLoadLODSwizzle[loadCoordCount] << ")\")\n"; } - sb << "__intrinsic_op\n"; sb << "T Load("; sb << "int" << loadCoordCount << " location"; if(isMultisample) @@ -544,7 +536,6 @@ for (int tt = 0; tt < kBaseTextureTypeCount; ++tt) { sb << "__target_intrinsic(glsl, \"texelFetch($P, ($0)." << kGLSLLoadCoordsSwizzle[loadCoordCount] << ", ($0)." << kGLSLLoadLODSwizzle[loadCoordCount] << ", $1)\")\n"; } - sb << "__intrinsic_op\n"; sb << "T Load("; sb << "int" << loadCoordCount << " location"; if(isMultisample) @@ -572,7 +563,7 @@ for (int tt = 0; tt < kBaseTextureTypeCount; ++tt) // this should have both `get` and `set` accessors. // subscript operator - sb << "__intrinsic_op __subscript(uint"; + sb << "__subscript(uint"; if(kBaseTextureTypes[tt].coordCount + isArray > 1) { sb << kBaseTextureTypes[tt].coordCount + isArray; @@ -587,16 +578,14 @@ for (int tt = 0; tt < kBaseTextureTypeCount; ++tt) sb << "__target_intrinsic(glsl, \"texture($p, $1)\")\n"; // TODO: only enable if IR is being used? - sb << "__intrinsic_op(sample)\n"; +// sb << "__intrinsic_op(sample)\n"; - sb << "__intrinsic_op\n"; sb << "T Sample(SamplerState s, "; sb << "float" << kBaseTextureTypes[tt].coordCount + isArray << " location);\n"; if( baseShape != TextureType::ShapeCube ) { sb << "__target_intrinsic(glsl, \"textureOffset($p, $1, $2)\")\n"; - sb << "__intrinsic_op\n"; sb << "T Sample(SamplerState s, "; sb << "float" << kBaseTextureTypes[tt].coordCount + isArray << " location, "; sb << "int" << kBaseTextureTypes[tt].coordCount << " offset);\n"; @@ -621,14 +610,12 @@ for (int tt = 0; tt < kBaseTextureTypeCount; ++tt) // `SampleBias()` sb << "__target_intrinsic(glsl, \"texture($p, $1, $2)\")\n"; - sb << "__intrinsic_op\n"; sb << "T SampleBias(SamplerState s, "; sb << "float" << kBaseTextureTypes[tt].coordCount + isArray << " location, float bias);\n"; if( baseShape != TextureType::ShapeCube ) { sb << "__target_intrinsic(glsl, \"textureOffset($p, $1, $2, $3)\")\n"; - sb << "__intrinsic_op\n"; sb << "T SampleBias(SamplerState s, "; sb << "float" << kBaseTextureTypes[tt].coordCount + isArray << " location, float bias, "; sb << "int" << kBaseTextureTypes[tt].coordCount << " offset);\n"; @@ -681,7 +668,6 @@ for (int tt = 0; tt < kBaseTextureTypeCount; ++tt) sb << ", vec" << baseCoordCount << "(0.0)"; sb << ")\")\n"; } - sb << "__intrinsic_op\n"; sb << "T SampleCmpLevelZero(SamplerComparisonState s, "; sb << "float" << kBaseTextureTypes[tt].coordCount + isArray << " location, "; sb << "float compareValue"; @@ -709,7 +695,7 @@ for (int tt = 0; tt < kBaseTextureTypeCount; ++tt) sb << "__target_intrinsic(glsl, \"textureGrad($p, $1, $2, $3)\")\n"; - sb << "__intrinsic_op(sampleGrad)\n"; +// sb << "__intrinsic_op(sampleGrad)\n"; sb << "T SampleGrad(SamplerState s, "; sb << "float" << kBaseTextureTypes[tt].coordCount + isArray << " location, "; sb << "float" << kBaseTextureTypes[tt].coordCount << " gradX, "; @@ -719,7 +705,7 @@ for (int tt = 0; tt < kBaseTextureTypeCount; ++tt) if( baseShape != TextureType::ShapeCube ) { sb << "__target_intrinsic(glsl, \"textureGradOffset($p, $1, $2, $3, $4)\")\n"; - sb << "__intrinsic_op(sampleGrad)\n"; +// sb << "__intrinsic_op(sampleGrad)\n"; sb << "T SampleGrad(SamplerState s, "; sb << "float" << kBaseTextureTypes[tt].coordCount + isArray << " location, "; sb << "float" << kBaseTextureTypes[tt].coordCount << " gradX, "; @@ -730,7 +716,6 @@ for (int tt = 0; tt < kBaseTextureTypeCount; ++tt) // `SampleLevel` sb << "__target_intrinsic(glsl, \"textureLod($p, $1, $2)\")\n"; - sb << "__intrinsic_op\n"; sb << "T SampleLevel(SamplerState s, "; sb << "float" << kBaseTextureTypes[tt].coordCount + isArray << " location, "; sb << "float level);\n"; @@ -738,7 +723,6 @@ for (int tt = 0; tt < kBaseTextureTypeCount; ++tt) if( baseShape != TextureType::ShapeCube ) { sb << "__target_intrinsic(glsl, \"textureLodOffset($p, $1, $2, $3)\")\n"; - sb << "__intrinsic_op\n"; sb << "T SampleLevel(SamplerState s, "; sb << "float" << kBaseTextureTypes[tt].coordCount + isArray << " location, "; sb << "float level, "; @@ -806,13 +790,11 @@ for (int tt = 0; tt < kBaseTextureTypeCount; ++tt) EMIT_LINE_DIRECTIVE(); sb << "__target_intrinsic(glsl, \"textureGather($p, $1, " << componentIndex << ")\")\n"; - sb << "__intrinsic_op\n"; sb << "vector Gather" << componentName << "(SamplerState s, "; sb << "float" << kBaseTextureTypes[tt].coordCount << " location);\n"; EMIT_LINE_DIRECTIVE(); sb << "__target_intrinsic(glsl, \"textureGatherOffset($p, $1, $2, " << componentIndex << ")\")\n"; - sb << "__intrinsic_op\n"; sb << "vector Gather" << componentName << "(SamplerState s, "; sb << "float" << kBaseTextureTypes[tt].coordCount << " location, "; sb << "int" << kBaseTextureTypes[tt].coordCount << " offset);\n"; @@ -825,7 +807,6 @@ for (int tt = 0; tt < kBaseTextureTypeCount; ++tt) EMIT_LINE_DIRECTIVE(); sb << "__target_intrinsic(glsl, \"textureGatherOffsets($p, $1, int" << kBaseTextureTypes[tt].coordCount << "[]($2, $3, $4, $5), " << componentIndex << ")\")\n"; - sb << "__intrinsic_op\n"; sb << "vector Gather" << componentName << "(SamplerState s, "; sb << "float" << kBaseTextureTypes[tt].coordCount << " location, "; sb << "int" << kBaseTextureTypes[tt].coordCount << " offset1, "; diff --git a/source/slang/hlsl.meta.slang b/source/slang/hlsl.meta.slang index dc1d4d8e8..cdf720006 100644 --- a/source/slang/hlsl.meta.slang +++ b/source/slang/hlsl.meta.slang @@ -4,29 +4,29 @@ typedef uint UINT; __generic __magic_type(HLSLAppendStructuredBufferType) struct AppendStructuredBuffer { - __intrinsic_op void Append(T value); + void Append(T value); - __intrinsic_op void GetDimensions( + void GetDimensions( out uint numStructs, out uint stride); }; __magic_type(HLSLByteAddressBufferType) struct ByteAddressBuffer { - __intrinsic_op void GetDimensions( + void GetDimensions( out uint dim); - __intrinsic_op uint Load(int location); - __intrinsic_op uint Load(int location, out uint status); + uint Load(int location); + uint Load(int location, out uint status); - __intrinsic_op uint2 Load2(int location); - __intrinsic_op uint2 Load2(int location, out uint status); + uint2 Load2(int location); + uint2 Load2(int location, out uint status); - __intrinsic_op uint3 Load3(int location); - __intrinsic_op uint3 Load3(int location, out uint status); + uint3 Load3(int location); + uint3 Load3(int location, out uint status); - __intrinsic_op uint4 Load4(int location); - __intrinsic_op uint4 Load4(int location, out uint status); + uint4 Load4(int location); + uint4 Load4(int location, out uint status); }; __generic @@ -37,12 +37,12 @@ __intrinsic_type(${{ }}) struct StructuredBuffer { - __intrinsic_op void GetDimensions( + void GetDimensions( out uint numStructs, out uint stride); - __intrinsic_op T Load(int location); - __intrinsic_op T Load(int location, out uint status); + T Load(int location); + T Load(int location, out uint status); __intrinsic_op(bufferLoad) __subscript(uint index) -> T; @@ -50,21 +50,21 @@ struct StructuredBuffer __generic __magic_type(HLSLConsumeStructuredBufferType) struct ConsumeStructuredBuffer { - __intrinsic_op T Consume(); + T Consume(); - __intrinsic_op void GetDimensions( + void GetDimensions( out uint numStructs, out uint stride); }; __generic __magic_type(HLSLInputPatchType) struct InputPatch { - __intrinsic_op __subscript(uint index) -> T; + __subscript(uint index) -> T; }; __generic __magic_type(HLSLOutputPatchType) struct OutputPatch { - __intrinsic_op __subscript(uint index) -> T { set; } + __subscript(uint index) -> T { set; } }; __magic_type(HLSLRWByteAddressBufferType) struct RWByteAddressBuffer @@ -72,110 +72,110 @@ __magic_type(HLSLRWByteAddressBufferType) struct RWByteAddressBuffer // Note(tfoley): supports alll operations from `ByteAddressBuffer` // TODO(tfoley): can this be made a sub-type? - __intrinsic_op void GetDimensions( + void GetDimensions( out uint dim); - __intrinsic_op uint Load(int location); - __intrinsic_op uint Load(int location, out uint status); + uint Load(int location); + uint Load(int location, out uint status); - __intrinsic_op uint2 Load2(int location); - __intrinsic_op uint2 Load2(int location, out uint status); + uint2 Load2(int location); + uint2 Load2(int location, out uint status); - __intrinsic_op uint3 Load3(int location); - __intrinsic_op uint3 Load3(int location, out uint status); + uint3 Load3(int location); + uint3 Load3(int location, out uint status); - __intrinsic_op uint4 Load4(int location); - __intrinsic_op uint4 Load4(int location, out uint status); + uint4 Load4(int location); + uint4 Load4(int location, out uint status); // Added operations: - __intrinsic_op void InterlockedAdd( + void InterlockedAdd( UINT dest, UINT value, out UINT original_value); - __intrinsic_op void InterlockedAdd( + void InterlockedAdd( UINT dest, UINT value); - __intrinsic_op void InterlockedAnd( + void InterlockedAnd( UINT dest, UINT value, out UINT original_value); - __intrinsic_op void InterlockedAnd( + void InterlockedAnd( UINT dest, UINT value); - __intrinsic_op void InterlockedCompareExchange( + void InterlockedCompareExchange( UINT dest, UINT compare_value, UINT value, out UINT original_value); - __intrinsic_op void InterlockedCompareExchange( + void InterlockedCompareExchange( UINT dest, UINT compare_value, UINT value); - __intrinsic_op void InterlockedCompareStore( + void InterlockedCompareStore( UINT dest, UINT compare_value, UINT value); - __intrinsic_op void InterlockedCompareStore( + void InterlockedCompareStore( UINT dest, UINT compare_value); - __intrinsic_op void InterlockedExchange( + void InterlockedExchange( UINT dest, UINT value, out UINT original_value); - __intrinsic_op void InterlockedExchange( + void InterlockedExchange( UINT dest, UINT value); - __intrinsic_op void InterlockedMax( + void InterlockedMax( UINT dest, UINT value, out UINT original_value); - __intrinsic_op void InterlockedMax( + void InterlockedMax( UINT dest, UINT value); - __intrinsic_op void InterlockedMin( + void InterlockedMin( UINT dest, UINT value, out UINT original_value); - __intrinsic_op void InterlockedMin( + void InterlockedMin( UINT dest, UINT value); - __intrinsic_op void InterlockedOr( + void InterlockedOr( UINT dest, UINT value, out UINT original_value); - __intrinsic_op void InterlockedOr( + void InterlockedOr( UINT dest, UINT value); - __intrinsic_op void InterlockedXor( + void InterlockedXor( UINT dest, UINT value, out UINT original_value); - __intrinsic_op void InterlockedXor( + void InterlockedXor( UINT dest, UINT value); - __intrinsic_op void Store( + void Store( uint address, uint value); - __intrinsic_op void Store2( + void Store2( uint address, uint2 value); - __intrinsic_op void Store3( + void Store3( uint address, uint3 value); - __intrinsic_op void Store4( + void Store4( uint address, uint4 value); }; @@ -188,18 +188,17 @@ __intrinsic_type(${{ }}) struct RWStructuredBuffer { - __intrinsic_op uint DecrementCounter(); + uint DecrementCounter(); - __intrinsic_op void GetDimensions( + void GetDimensions( out uint numStructs, out uint stride); - __intrinsic_op uint IncrementCounter(); + uint IncrementCounter(); - __intrinsic_op T Load(int location); - __intrinsic_op T Load(int location, out uint status); + T Load(int location); + T Load(int location, out uint status); - __intrinsic_op __subscript(uint index) -> T { __intrinsic_op(bufferLoad) @@ -231,99 +230,96 @@ __generic __magic_type(HLSLTriangleStreamType) struct TriangleStream // Note(tfoley): Trying to systematically add all the HLSL builtins // Try to terminate the current draw or dispatch call (HLSL SM 4.0) -__intrinsic_op void abort(); +void abort(); // Absolute value (HLSL SM 1.0) -__generic __intrinsic_op T abs(T x); -__generic __intrinsic_op vector abs(vector x); -__generic __intrinsic_op matrix abs(matrix x); +__generic T abs(T x); +__generic vector abs(vector x); +__generic matrix abs(matrix x); // Inverse cosine (HLSL SM 1.0) -__generic __intrinsic_op T acos(T x); -__generic __intrinsic_op vector acos(vector x); -__generic __intrinsic_op matrix acos(matrix x); +__generic T acos(T x); +__generic vector acos(vector x); +__generic matrix acos(matrix x); // Test if all components are non-zero (HLSL SM 1.0) -__generic __intrinsic_op T all(T x); -__generic __intrinsic_op vector all(vector x); -__generic __intrinsic_op matrix all(matrix x); +__generic T all(T x); +__generic vector all(vector x); +__generic matrix all(matrix x); // Barrier for writes to all memory spaces (HLSL SM 5.0) -__intrinsic_op void AllMemoryBarrier(); +void AllMemoryBarrier(); // Thread-group sync and barrier for writes to all memory spaces (HLSL SM 5.0) -__intrinsic_op void AllMemoryBarrierWithGroupSync(); +void AllMemoryBarrierWithGroupSync(); // Test if any components is non-zero (HLSL SM 1.0) -__generic __intrinsic_op T any(T x); -__generic __intrinsic_op vector any(vector x); -__generic __intrinsic_op matrix any(matrix x); +__generic T any(T x); +__generic vector any(vector x); +__generic matrix any(matrix x); // Reinterpret bits as a double (HLSL SM 5.0) -__intrinsic_op double asdouble(uint lowbits, uint highbits); +double asdouble(uint lowbits, uint highbits); // Reinterpret bits as a float (HLSL SM 4.0) -__intrinsic_op float asfloat( int x); -__intrinsic_op float asfloat(uint x); -__generic __intrinsic_op vector asfloat(vector< int,N> x); -__generic __intrinsic_op vector asfloat(vector x); -__generic __intrinsic_op matrix asfloat(matrix< int,N,M> x); -__generic __intrinsic_op matrix asfloat(matrix x); +float asfloat( int x); +float asfloat(uint x); +__generic vector asfloat(vector< int,N> x); +__generic vector asfloat(vector x); +__generic matrix asfloat(matrix< int,N,M> x); +__generic matrix asfloat(matrix x); // Inverse sine (HLSL SM 1.0) -__generic __intrinsic_op T asin(T x); -__generic __intrinsic_op vector asin(vector x); -__generic __intrinsic_op matrix asin(matrix x); +__generic T asin(T x); +__generic vector asin(vector x); +__generic matrix asin(matrix x); // Reinterpret bits as an int (HLSL SM 4.0) -__intrinsic_op int asint(float x); -__intrinsic_op int asint(uint x); -__generic __intrinsic_op vector asint(vector x); -__generic __intrinsic_op vector asint(vector x); -__generic __intrinsic_op matrix asint(matrix x); -__generic __intrinsic_op matrix asint(matrix x); +int asint(float x); +int asint(uint x); +__generic vector asint(vector x); +__generic vector asint(vector x); +__generic matrix asint(matrix x); +__generic matrix asint(matrix x); // Reinterpret bits of double as a uint (HLSL SM 5.0) -__intrinsic_op void asuint(double value, out uint lowbits, out uint highbits); +void asuint(double value, out uint lowbits, out uint highbits); // Reinterpret bits as a uint (HLSL SM 4.0) -__intrinsic_op uint asuint(float x); -__intrinsic_op uint asuint(int x); -__generic __intrinsic_op vector asuint(vector x); -__generic __intrinsic_op vector asuint(vector x); -__generic __intrinsic_op matrix asuint(matrix x); -__generic __intrinsic_op matrix asuint(matrix x); +uint asuint(float x); +uint asuint(int x); +__generic vector asuint(vector x); +__generic vector asuint(vector x); +__generic matrix asuint(matrix x); +__generic matrix asuint(matrix x); // Inverse tangent (HLSL SM 1.0) -__generic __intrinsic_op T atan(T x); -__generic __intrinsic_op vector atan(vector x); -__generic __intrinsic_op matrix atan(matrix x); +__generic T atan(T x); +__generic vector atan(vector x); +__generic matrix atan(matrix x); __generic __target_intrinsic(glsl,"atan($0,$1)") -__intrinsic_op T atan2(T y, T x); __generic __target_intrinsic(glsl,"atan($0,$1)") -__intrinsic_op vector atan2(vector y, vector x); __generic __target_intrinsic(glsl,"atan($0,$1)") -__intrinsic_op matrix atan2(matrix y, matrix x); // Ceiling (HLSL SM 1.0) -__generic __intrinsic_op T ceil(T x); -__generic __intrinsic_op vector ceil(vector x); -__generic __intrinsic_op matrix ceil(matrix x); +__generic T ceil(T x); +__generic vector ceil(vector x); +__generic matrix ceil(matrix x); // Check access status to tiled resource -__intrinsic_op bool CheckAccessFullyMapped(uint status); +bool CheckAccessFullyMapped(uint status); // Clamp (HLSL SM 1.0) __generic T clamp(T x, T min, T max); @@ -331,9 +327,9 @@ __generic vector clamp(vector matrix clamp(matrix x, matrix min, matrix max); // Clip (discard) fragment conditionally -__generic __intrinsic_op void clip(T x); -__generic __intrinsic_op void clip(vector x); -__generic __intrinsic_op void clip(matrix x); +__generic void clip(T x); +__generic void clip(vector x); +__generic void clip(matrix x); // Cosine __generic T cos(T x); @@ -341,360 +337,348 @@ __generic vector cos(vector matrix cos(matrix x); // Hyperbolic cosine -__generic __intrinsic_op T cosh(T x); -__generic __intrinsic_op vector cosh(vector x); -__generic __intrinsic_op matrix cosh(matrix x); +__generic T cosh(T x); +__generic vector cosh(vector x); +__generic matrix cosh(matrix x); // Population count -__intrinsic_op uint countbits(uint value); +uint countbits(uint value); // Cross product -__generic __intrinsic_op vector cross(vector x, vector y); +__generic vector cross(vector x, vector y); // Convert encoded color -__intrinsic_op int4 D3DCOLORtoUBYTE4(float4 x); +int4 D3DCOLORtoUBYTE4(float4 x); // Partial-difference derivatives __generic __target_intrinsic(glsl, dFdx) -__intrinsic_op T ddx(T x); + __generic __target_intrinsic(glsl, dFdx) -__intrinsic_op vector ddx(vector x); + __generic __target_intrinsic(glsl, dFdx) -__intrinsic_op matrix ddx(matrix x); __generic __glsl_extension(GL_ARB_derivative_control) __target_intrinsic(glsl, dFdxCoarse) -__intrinsic_op T ddx_coarse(T x); + __generic __glsl_extension(GL_ARB_derivative_control) __target_intrinsic(glsl, dFdxCoarse) -__intrinsic_op vector ddx_coarse(vector x); + __generic __glsl_extension(GL_ARB_derivative_control) __target_intrinsic(glsl, dFdxCoarse) -__intrinsic_op matrix ddx_coarse(matrix x); __generic __glsl_extension(GL_ARB_derivative_control) __target_intrinsic(glsl, dFdxFine) -__intrinsic_op T ddx_fine(T x); + __generic __glsl_extension(GL_ARB_derivative_control) __target_intrinsic(glsl, dFdxFine) -__intrinsic_op vector ddx_fine(vector x); + __generic __glsl_extension(GL_ARB_derivative_control) __target_intrinsic(glsl, dFdxFine) -__intrinsic_op matrix ddx_fine(matrix x); __generic __target_intrinsic(glsl, dFdy) -__intrinsic_op T ddy(T x); + __generic __target_intrinsic(glsl, dFdy) -__intrinsic_op vector ddy(vector x); + __generic __target_intrinsic(glsl, dFdy) -__intrinsic_op matrix ddy(matrix x); __generic __glsl_extension(GL_ARB_derivative_control) __target_intrinsic(glsl, dFdyCoarse) -__intrinsic_op T ddy_coarse(T x); + __generic __glsl_extension(GL_ARB_derivative_control) __target_intrinsic(glsl, dFdyCoarse) -__intrinsic_op vector ddy_coarse(vector x); + __generic __glsl_extension(GL_ARB_derivative_control) __target_intrinsic(glsl, dFdyCoarse) -__intrinsic_op matrix ddy_coarse(matrix x); __generic __glsl_extension(GL_ARB_derivative_control) __target_intrinsic(glsl, dFdyFine) -__intrinsic_op T ddy_fine(T x); + __generic __glsl_extension(GL_ARB_derivative_control) __target_intrinsic(glsl, dFdyFine) -__intrinsic_op vector ddy_fine(vector x); + __generic __glsl_extension(GL_ARB_derivative_control) __target_intrinsic(glsl, dFdyFine) -__intrinsic_op matrix ddy_fine(matrix x); // Radians to degrees -__generic __intrinsic_op T degrees(T x); -__generic __intrinsic_op vector degrees(vector x); -__generic __intrinsic_op matrix degrees(matrix x); +__generic T degrees(T x); +__generic vector degrees(vector x); +__generic matrix degrees(matrix x); // Matrix determinant -__generic __intrinsic_op T determinant(matrix m); +__generic T determinant(matrix m); // Barrier for device memory -__intrinsic_op void DeviceMemoryBarrier(); -__intrinsic_op void DeviceMemoryBarrierWithGroupSync(); +void DeviceMemoryBarrier(); +void DeviceMemoryBarrierWithGroupSync(); // Vector distance -__generic __intrinsic_op T distance(vector x, vector y); +__generic T distance(vector x, vector y); // Vector dot product -__generic __intrinsic_op T dot(vector x, vector y); +__generic T dot(vector x, vector y); // Helper for computing distance terms for lighting (obsolete) -__generic __intrinsic_op vector dst(vector x, vector y); +__generic vector dst(vector x, vector y); // Error message -// __intrinsic_op void errorf( string format, ... ); +// void errorf( string format, ... ); // Attribute evaluation -__generic __intrinsic_op T EvaluateAttributeAtCentroid(T x); -__generic __intrinsic_op vector EvaluateAttributeAtCentroid(vector x); -__generic __intrinsic_op matrix EvaluateAttributeAtCentroid(matrix x); +__generic T EvaluateAttributeAtCentroid(T x); +__generic vector EvaluateAttributeAtCentroid(vector x); +__generic matrix EvaluateAttributeAtCentroid(matrix x); -__generic __intrinsic_op T EvaluateAttributeAtSample(T x, uint sampleindex); -__generic __intrinsic_op vector EvaluateAttributeAtSample(vector x, uint sampleindex); -__generic __intrinsic_op matrix EvaluateAttributeAtSample(matrix x, uint sampleindex); +__generic T EvaluateAttributeAtSample(T x, uint sampleindex); +__generic vector EvaluateAttributeAtSample(vector x, uint sampleindex); +__generic matrix EvaluateAttributeAtSample(matrix x, uint sampleindex); -__generic __intrinsic_op T EvaluateAttributeSnapped(T x, int2 offset); -__generic __intrinsic_op vector EvaluateAttributeSnapped(vector x, int2 offset); -__generic __intrinsic_op matrix EvaluateAttributeSnapped(matrix x, int2 offset); +__generic T EvaluateAttributeSnapped(T x, int2 offset); +__generic vector EvaluateAttributeSnapped(vector x, int2 offset); +__generic matrix EvaluateAttributeSnapped(matrix x, int2 offset); // Base-e exponent -__generic __intrinsic_op T exp(T x); -__generic __intrinsic_op vector exp(vector x); -__generic __intrinsic_op matrix exp(matrix x); +__generic T exp(T x); +__generic vector exp(vector x); +__generic matrix exp(matrix x); // Base-2 exponent -__generic __intrinsic_op T exp2(T x); -__generic __intrinsic_op vector exp2(vector x); -__generic __intrinsic_op matrix exp2(matrix x); +__generic T exp2(T x); +__generic vector exp2(vector x); +__generic matrix exp2(matrix x); // Convert 16-bit float stored in low bits of integer -__intrinsic_op float f16tof32(uint value); -__generic __intrinsic_op vector f16tof32(vector value); +float f16tof32(uint value); +__generic vector f16tof32(vector value); // Convert to 16-bit float stored in low bits of integer -__intrinsic_op uint f32tof16(float value); -__generic __intrinsic_op vector f32tof16(vector value); +uint f32tof16(float value); +__generic vector f32tof16(vector value); // Flip surface normal to face forward, if needed -__generic __intrinsic_op vector faceforward(vector n, vector i, vector ng); +__generic vector faceforward(vector n, vector i, vector ng); // Find first set bit starting at high bit and working down -__intrinsic_op int firstbithigh(int value); -__generic __intrinsic_op vector firstbithigh(vector value); +int firstbithigh(int value); +__generic vector firstbithigh(vector value); -__intrinsic_op uint firstbithigh(uint value); -__generic __intrinsic_op vector firstbithigh(vector value); +uint firstbithigh(uint value); +__generic vector firstbithigh(vector value); // Find first set bit starting at low bit and working up -__intrinsic_op int firstbitlow(int value); -__generic __intrinsic_op vector firstbitlow(vector value); +int firstbitlow(int value); +__generic vector firstbitlow(vector value); -__intrinsic_op uint firstbitlow(uint value); -__generic __intrinsic_op vector firstbitlow(vector value); +uint firstbitlow(uint value); +__generic vector firstbitlow(vector value); // Floor (HLSL SM 1.0) -__generic __intrinsic_op T floor(T x); -__generic __intrinsic_op vector floor(vector x); -__generic __intrinsic_op matrix floor(matrix x); +__generic T floor(T x); +__generic vector floor(vector x); +__generic matrix floor(matrix x); // Fused multiply-add for doubles -__intrinsic_op double fma(double a, double b, double c); -__generic __intrinsic_op vector fma(vector a, vector b, vector c); -__generic __intrinsic_op matrix fma(matrix a, matrix b, matrix c); +double fma(double a, double b, double c); +__generic vector fma(vector a, vector b, vector c); +__generic matrix fma(matrix a, matrix b, matrix c); // Floating point remainder of x/y -__generic __intrinsic_op T fmod(T x, T y); -__generic __intrinsic_op vector fmod(vector x, vector y); -__generic __intrinsic_op matrix fmod(matrix x, matrix y); +__generic T fmod(T x, T y); +__generic vector fmod(vector x, vector y); +__generic matrix fmod(matrix x, matrix y); // Fractional part __generic __target_intrinsic(glsl, fract) -__intrinsic_op T frac(T x); __generic __target_intrinsic(glsl, fract) -__intrinsic_op vector frac(vector x); __generic __target_intrinsic(glsl, fract) -__intrinsic_op matrix frac(matrix x); // Split float into mantissa and exponent -__generic __intrinsic_op T frexp(T x, out T exp); -__generic __intrinsic_op vector frexp(vector x, out vector exp); -__generic __intrinsic_op matrix frexp(matrix x, out matrix exp); +__generic T frexp(T x, out T exp); +__generic vector frexp(vector x, out vector exp); +__generic matrix frexp(matrix x, out matrix exp); // Texture filter width -__generic __intrinsic_op T fwidth(T x); -__generic __intrinsic_op vector fwidth(vector x); -__generic __intrinsic_op matrix fwidth(matrix x); +__generic T fwidth(T x); +__generic vector fwidth(vector x); +__generic matrix fwidth(matrix x); // Get number of samples in render target -__intrinsic_op uint GetRenderTargetSampleCount(); +uint GetRenderTargetSampleCount(); // Get position of given sample -__intrinsic_op float2 GetRenderTargetSamplePosition(int Index); +float2 GetRenderTargetSamplePosition(int Index); // Group memory barrier -__intrinsic_op void GroupMemoryBarrier(); -__intrinsic_op void GroupMemoryBarrierWithGroupSync(); +void GroupMemoryBarrier(); +void GroupMemoryBarrierWithGroupSync(); // Atomics -__intrinsic_op void InterlockedAdd(in out int dest, int value, out int original_value); -__intrinsic_op void InterlockedAdd(in out uint dest, uint value, out uint original_value); +void InterlockedAdd(in out int dest, int value, out int original_value); +void InterlockedAdd(in out uint dest, uint value, out uint original_value); -__intrinsic_op void InterlockedAnd(in out int dest, int value, out int original_value); -__intrinsic_op void InterlockedAnd(in out uint dest, uint value, out uint original_value); +void InterlockedAnd(in out int dest, int value, out int original_value); +void InterlockedAnd(in out uint dest, uint value, out uint original_value); -__intrinsic_op void InterlockedCompareExchange(in out int dest, int compare_value, int value, out int original_value); -__intrinsic_op void InterlockedCompareExchange(in out uint dest, uint compare_value, uint value, out uint original_value); +void InterlockedCompareExchange(in out int dest, int compare_value, int value, out int original_value); +void InterlockedCompareExchange(in out uint dest, uint compare_value, uint value, out uint original_value); -__intrinsic_op void InterlockedCompareStore(in out int dest, int compare_value, int value); -__intrinsic_op void InterlockedCompareStore(in out uint dest, uint compare_value, uint value); +void InterlockedCompareStore(in out int dest, int compare_value, int value); +void InterlockedCompareStore(in out uint dest, uint compare_value, uint value); -__intrinsic_op void InterlockedExchange(in out int dest, int value, out int original_value); -__intrinsic_op void InterlockedExchange(in out uint dest, uint value, out uint original_value); +void InterlockedExchange(in out int dest, int value, out int original_value); +void InterlockedExchange(in out uint dest, uint value, out uint original_value); -__intrinsic_op void InterlockedMax(in out int dest, int value, out int original_value); -__intrinsic_op void InterlockedMax(in out uint dest, uint value, out uint original_value); +void InterlockedMax(in out int dest, int value, out int original_value); +void InterlockedMax(in out uint dest, uint value, out uint original_value); -__intrinsic_op void InterlockedMin(in out int dest, int value, out int original_value); -__intrinsic_op void InterlockedMin(in out uint dest, uint value, out uint original_value); +void InterlockedMin(in out int dest, int value, out int original_value); +void InterlockedMin(in out uint dest, uint value, out uint original_value); -__intrinsic_op void InterlockedOr(in out int dest, int value, out int original_value); -__intrinsic_op void InterlockedOr(in out uint dest, uint value, out uint original_value); +void InterlockedOr(in out int dest, int value, out int original_value); +void InterlockedOr(in out uint dest, uint value, out uint original_value); -__intrinsic_op void InterlockedXor(in out int dest, int value, out int original_value); -__intrinsic_op void InterlockedXor(in out uint dest, uint value, out uint original_value); +void InterlockedXor(in out int dest, int value, out int original_value); +void InterlockedXor(in out uint dest, uint value, out uint original_value); // Is floating-point value finite? -__generic __intrinsic_op bool isfinite(T x); -__generic __intrinsic_op vector isfinite(vector x); -__generic __intrinsic_op matrix isfinite(matrix x); +__generic bool isfinite(T x); +__generic vector isfinite(vector x); +__generic matrix isfinite(matrix x); // Is floating-point value infinite? -__generic __intrinsic_op bool isinf(T x); -__generic __intrinsic_op vector isinf(vector x); -__generic __intrinsic_op matrix isinf(matrix x); +__generic bool isinf(T x); +__generic vector isinf(vector x); +__generic matrix isinf(matrix x); // Is floating-point value not-a-number? -__generic __intrinsic_op bool isnan(T x); -__generic __intrinsic_op vector isnan(vector x); -__generic __intrinsic_op matrix isnan(matrix x); +__generic bool isnan(T x); +__generic vector isnan(vector x); +__generic matrix isnan(matrix x); // Construct float from mantissa and exponent -__generic __intrinsic_op T ldexp(T x, T exp); -__generic __intrinsic_op vector ldexp(vector x, vector exp); -__generic __intrinsic_op matrix ldexp(matrix x, matrix exp); +__generic T ldexp(T x, T exp); +__generic vector ldexp(vector x, vector exp); +__generic matrix ldexp(matrix x, matrix exp); // Vector length -__generic __intrinsic_op T length(vector x); +__generic T length(vector x); // Linear interpolation __generic __target_intrinsic(glsl, mix) -__intrinsic_op T lerp(T x, T y, T s); __generic __target_intrinsic(glsl, mix) -__intrinsic_op vector lerp(vector x, vector y, vector s); __generic __target_intrinsic(glsl, mix) -__intrinsic_op matrix lerp(matrix x, matrix y, matrix s); // Legacy lighting function (obsolete) -__intrinsic_op float4 lit(float n_dot_l, float n_dot_h, float m); +float4 lit(float n_dot_l, float n_dot_h, float m); // Base-e logarithm -__generic __intrinsic_op T log(T x); -__generic __intrinsic_op vector log(vector x); -__generic __intrinsic_op matrix log(matrix x); +__generic T log(T x); +__generic vector log(vector x); +__generic matrix log(matrix x); // Base-10 logarithm -__generic __intrinsic_op T log10(T x); -__generic __intrinsic_op vector log10(vector x); -__generic __intrinsic_op matrix log10(matrix x); +__generic T log10(T x); +__generic vector log10(vector x); +__generic matrix log10(matrix x); // Base-2 logarithm -__generic __intrinsic_op T log2(T x); -__generic __intrinsic_op vector log2(vector x); -__generic __intrinsic_op matrix log2(matrix x); +__generic T log2(T x); +__generic vector log2(vector x); +__generic matrix log2(matrix x); // multiply-add -__generic __intrinsic_op T mad(T mvalue, T avalue, T bvalue); -__generic __intrinsic_op vector mad(vector mvalue, vector avalue, vector bvalue); -__generic __intrinsic_op matrix mad(matrix mvalue, matrix avalue, matrix bvalue); +__generic T mad(T mvalue, T avalue, T bvalue); +__generic vector mad(vector mvalue, vector avalue, vector bvalue); +__generic matrix mad(matrix mvalue, matrix avalue, matrix bvalue); // maximum -__generic __intrinsic_op T max(T x, T y); -__generic __intrinsic_op vector max(vector x, vector y); -__generic __intrinsic_op matrix max(matrix x, matrix y); +__generic T max(T x, T y); +__generic vector max(vector x, vector y); +__generic matrix max(matrix x, matrix y); // minimum -__generic __intrinsic_op T min(T x, T y); -__generic __intrinsic_op vector min(vector x, vector y); -__generic __intrinsic_op matrix min(matrix x, matrix y); +__generic T min(T x, T y); +__generic vector min(vector x, vector y); +__generic matrix min(matrix x, matrix y); // split into integer and fractional parts (both with same sign) -__generic __intrinsic_op T modf(T x, out T ip); -__generic __intrinsic_op vector modf(vector x, out vector ip); -__generic __intrinsic_op matrix modf(matrix x, out matrix ip); +__generic T modf(T x, out T ip); +__generic vector modf(vector x, out vector ip); +__generic matrix modf(matrix x, out matrix ip); // msad4 (whatever that is) -__intrinsic_op uint4 msad4(uint reference, uint2 source, uint4 accum); +uint4 msad4(uint reference, uint2 source, uint4 accum); // General inner products // scalar-scalar -__generic __intrinsic_op T mul(T x, T y); +__generic T mul(T x, T y); // scalar-vector and vector-scalar -__generic __intrinsic_op vector mul(vector x, T y); -__generic __intrinsic_op vector mul(T x, vector y); +__generic vector mul(vector x, T y); +__generic vector mul(T x, vector y); // scalar-matrix and matrix-scalar -__generic __intrinsic_op matrix mul(matrix x, T y); -__generic __intrinsic_op matrix mul(T x, matrix y); +__generic matrix mul(matrix x, T y); +__generic matrix mul(T x, matrix y); // vector-vector (dot product) __generic __intrinsic_op(dot) T mul(vector x, vector y); @@ -709,86 +693,86 @@ __generic __intrinsic_op( __generic __intrinsic_op(mulMatrixMatrix) matrix mul(matrix x, matrix y); // noise (deprecated) -__intrinsic_op float noise(float x); -__generic __intrinsic_op float noise(vector x); +float noise(float x); +__generic float noise(vector x); // Normalize a vector -__generic __intrinsic_op vector normalize(vector x); +__generic vector normalize(vector x); // Raise to a power -__generic __intrinsic_op T pow(T x, T y); -__generic __intrinsic_op vector pow(vector x, vector y); -__generic __intrinsic_op matrix pow(matrix x, matrix y); +__generic T pow(T x, T y); +__generic vector pow(vector x, vector y); +__generic matrix pow(matrix x, matrix y); // Output message -// __intrinsic_op void printf( string format, ... ); +// void printf( string format, ... ); // Tessellation factor fixup routines -__intrinsic_op void Process2DQuadTessFactorsAvg( +void Process2DQuadTessFactorsAvg( in float4 RawEdgeFactors, in float2 InsideScale, out float4 RoundedEdgeTessFactors, out float2 RoundedInsideTessFactors, out float2 UnroundedInsideTessFactors); -__intrinsic_op void Process2DQuadTessFactorsMax( +void Process2DQuadTessFactorsMax( in float4 RawEdgeFactors, in float2 InsideScale, out float4 RoundedEdgeTessFactors, out float2 RoundedInsideTessFactors, out float2 UnroundedInsideTessFactors); -__intrinsic_op void Process2DQuadTessFactorsMin( +void Process2DQuadTessFactorsMin( in float4 RawEdgeFactors, in float2 InsideScale, out float4 RoundedEdgeTessFactors, out float2 RoundedInsideTessFactors, out float2 UnroundedInsideTessFactors); -__intrinsic_op void ProcessIsolineTessFactors( +void ProcessIsolineTessFactors( in float RawDetailFactor, in float RawDensityFactor, out float RoundedDetailFactor, out float RoundedDensityFactor); -__intrinsic_op void ProcessQuadTessFactorsAvg( +void ProcessQuadTessFactorsAvg( in float4 RawEdgeFactors, in float InsideScale, out float4 RoundedEdgeTessFactors, out float2 RoundedInsideTessFactors, out float2 UnroundedInsideTessFactors); -__intrinsic_op void ProcessQuadTessFactorsMax( +void ProcessQuadTessFactorsMax( in float4 RawEdgeFactors, in float InsideScale, out float4 RoundedEdgeTessFactors, out float2 RoundedInsideTessFactors, out float2 UnroundedInsideTessFactors); -__intrinsic_op void ProcessQuadTessFactorsMin( +void ProcessQuadTessFactorsMin( in float4 RawEdgeFactors, in float InsideScale, out float4 RoundedEdgeTessFactors, out float2 RoundedInsideTessFactors, out float2 UnroundedInsideTessFactors); -__intrinsic_op void ProcessTriTessFactorsAvg( +void ProcessTriTessFactorsAvg( in float3 RawEdgeFactors, in float InsideScale, out float3 RoundedEdgeTessFactors, out float RoundedInsideTessFactor, out float UnroundedInsideTessFactor); -__intrinsic_op void ProcessTriTessFactorsMax( +void ProcessTriTessFactorsMax( in float3 RawEdgeFactors, in float InsideScale, out float3 RoundedEdgeTessFactors, out float RoundedInsideTessFactor, out float UnroundedInsideTessFactor); -__intrinsic_op void ProcessTriTessFactorsMin( +void ProcessTriTessFactorsMin( in float3 RawEdgeFactors, in float InsideScale, out float3 RoundedEdgeTessFactors, @@ -796,38 +780,36 @@ __intrinsic_op void ProcessTriTessFactorsMin( out float UnroundedInsideTessFactors); // Degrees to radians -__generic __intrinsic_op T radians(T x); -__generic __intrinsic_op vector radians(vector x); -__generic __intrinsic_op matrix radians(matrix x); +__generic T radians(T x); +__generic vector radians(vector x); +__generic matrix radians(matrix x); // Approximate reciprocal -__generic __intrinsic_op T rcp(T x); -__generic __intrinsic_op vector rcp(vector x); -__generic __intrinsic_op matrix rcp(matrix x); +__generic T rcp(T x); +__generic vector rcp(vector x); +__generic matrix rcp(matrix x); // Reflect incident vector across plane with given normal __generic -__intrinsic_op vector reflect(vector i, vector n); // Refract incident vector given surface normal and index of refraction __generic -__intrinsic_op vector refract(vector i, vector n, float eta); // Reverse order of bits -__intrinsic_op uint reversebits(uint value); +uint reversebits(uint value); __generic vector reversebits(vector value); // Round-to-nearest -__generic __intrinsic_op T round(T x); -__generic __intrinsic_op vector round(vector x); -__generic __intrinsic_op matrix round(matrix x); +__generic T round(T x); +__generic vector round(vector x); +__generic matrix round(matrix x); // Reciprocal of square root -__generic __intrinsic_op T rsqrt(T x); -__generic __intrinsic_op vector rsqrt(vector x); -__generic __intrinsic_op matrix rsqrt(matrix x); +__generic T rsqrt(T x); +__generic vector rsqrt(vector x); +__generic matrix rsqrt(matrix x); // Clamp value to [0,1] range __generic @@ -875,9 +857,9 @@ matrix saturate(matrix x) // Extract sign of value -__generic __intrinsic_op int sign(T x); -__generic __intrinsic_op vector sign(vector x); -__generic __intrinsic_op matrix sign(matrix x); +__generic int sign(T x); +__generic vector sign(vector x); +__generic matrix sign(matrix x); // Sine @@ -886,127 +868,127 @@ __generic vector sin(vector matrix sin(matrix x); // Sine and cosine -__generic __intrinsic_op void sincos(T x, out T s, out T c); -__generic __intrinsic_op void sincos(vector x, out vector s, out vector c); -__generic __intrinsic_op void sincos(matrix x, out matrix s, out matrix c); +__generic void sincos(T x, out T s, out T c); +__generic void sincos(vector x, out vector s, out vector c); +__generic void sincos(matrix x, out matrix s, out matrix c); // Hyperbolic Sine -__generic __intrinsic_op T sinh(T x); -__generic __intrinsic_op vector sinh(vector x); -__generic __intrinsic_op matrix sinh(matrix x); +__generic T sinh(T x); +__generic vector sinh(vector x); +__generic matrix sinh(matrix x); // Smooth step (Hermite interpolation) -__generic __intrinsic_op T smoothstep(T min, T max, T x); -__generic __intrinsic_op vector smoothstep(vector min, vector max, vector x); -__generic __intrinsic_op matrix smoothstep(matrix min, matrix max, matrix x); +__generic T smoothstep(T min, T max, T x); +__generic vector smoothstep(vector min, vector max, vector x); +__generic matrix smoothstep(matrix min, matrix max, matrix x); // Square root -__generic __intrinsic_op T sqrt(T x); -__generic __intrinsic_op vector sqrt(vector x); -__generic __intrinsic_op matrix sqrt(matrix x); +__generic T sqrt(T x); +__generic vector sqrt(vector x); +__generic matrix sqrt(matrix x); // Step function -__generic __intrinsic_op T step(T y, T x); -__generic __intrinsic_op vector step(vector y, vector x); -__generic __intrinsic_op matrix step(matrix y, matrix x); +__generic T step(T y, T x); +__generic vector step(vector y, vector x); +__generic matrix step(matrix y, matrix x); // Tangent -__generic __intrinsic_op T tan(T x); -__generic __intrinsic_op vector tan(vector x); -__generic __intrinsic_op matrix tan(matrix x); +__generic T tan(T x); +__generic vector tan(vector x); +__generic matrix tan(matrix x); // Hyperbolic tangent -__generic __intrinsic_op T tanh(T x); -__generic __intrinsic_op vector tanh(vector x); -__generic __intrinsic_op matrix tanh(matrix x); +__generic T tanh(T x); +__generic vector tanh(vector x); +__generic matrix tanh(matrix x); // Legacy texture-fetch operations /* -__intrinsic_op float4 tex1D(sampler1D s, float t); -__intrinsic_op float4 tex1D(sampler1D s, float t, float ddx, float ddy); -__intrinsic_op float4 tex1Dbias(sampler1D s, float4 t); -__intrinsic_op float4 tex1Dgrad(sampler1D s, float t, float ddx, float ddy); -__intrinsic_op float4 tex1Dlod(sampler1D s, float4 t); -__intrinsic_op float4 tex1Dproj(sampler1D s, float4 t); - -__intrinsic_op float4 tex2D(sampler2D s, float2 t); -__intrinsic_op float4 tex2D(sampler2D s, float2 t, float2 ddx, float2 ddy); -__intrinsic_op float4 tex2Dbias(sampler2D s, float4 t); -__intrinsic_op float4 tex2Dgrad(sampler2D s, float2 t, float2 ddx, float2 ddy); -__intrinsic_op float4 tex2Dlod(sampler2D s, float4 t); -__intrinsic_op float4 tex2Dproj(sampler2D s, float4 t); - -__intrinsic_op float4 tex3D(sampler3D s, float3 t); -__intrinsic_op float4 tex3D(sampler3D s, float3 t, float3 ddx, float3 ddy); -__intrinsic_op float4 tex3Dbias(sampler3D s, float4 t); -__intrinsic_op float4 tex3Dgrad(sampler3D s, float3 t, float3 ddx, float3 ddy); -__intrinsic_op float4 tex3Dlod(sampler3D s, float4 t); -__intrinsic_op float4 tex3Dproj(sampler3D s, float4 t); - -__intrinsic_op float4 texCUBE(samplerCUBE s, float3 t); -__intrinsic_op float4 texCUBE(samplerCUBE s, float3 t, float3 ddx, float3 ddy); -__intrinsic_op float4 texCUBEbias(samplerCUBE s, float4 t); -__intrinsic_op float4 texCUBEgrad(samplerCUBE s, float3 t, float3 ddx, float3 ddy); -__intrinsic_op float4 texCUBElod(samplerCUBE s, float4 t); -__intrinsic_op float4 texCUBEproj(samplerCUBE s, float4 t); +float4 tex1D(sampler1D s, float t); +float4 tex1D(sampler1D s, float t, float ddx, float ddy); +float4 tex1Dbias(sampler1D s, float4 t); +float4 tex1Dgrad(sampler1D s, float t, float ddx, float ddy); +float4 tex1Dlod(sampler1D s, float4 t); +float4 tex1Dproj(sampler1D s, float4 t); + +float4 tex2D(sampler2D s, float2 t); +float4 tex2D(sampler2D s, float2 t, float2 ddx, float2 ddy); +float4 tex2Dbias(sampler2D s, float4 t); +float4 tex2Dgrad(sampler2D s, float2 t, float2 ddx, float2 ddy); +float4 tex2Dlod(sampler2D s, float4 t); +float4 tex2Dproj(sampler2D s, float4 t); + +float4 tex3D(sampler3D s, float3 t); +float4 tex3D(sampler3D s, float3 t, float3 ddx, float3 ddy); +float4 tex3Dbias(sampler3D s, float4 t); +float4 tex3Dgrad(sampler3D s, float3 t, float3 ddx, float3 ddy); +float4 tex3Dlod(sampler3D s, float4 t); +float4 tex3Dproj(sampler3D s, float4 t); + +float4 texCUBE(samplerCUBE s, float3 t); +float4 texCUBE(samplerCUBE s, float3 t, float3 ddx, float3 ddy); +float4 texCUBEbias(samplerCUBE s, float4 t); +float4 texCUBEgrad(samplerCUBE s, float3 t, float3 ddx, float3 ddy); +float4 texCUBElod(samplerCUBE s, float4 t); +float4 texCUBEproj(samplerCUBE s, float4 t); */ // Matrix transpose -__generic __intrinsic_op matrix transpose(matrix x); +__generic matrix transpose(matrix x); // Truncate to integer -__generic __intrinsic_op T trunc(T x); -__generic __intrinsic_op vector trunc(vector x); -__generic __intrinsic_op matrix trunc(matrix x); +__generic T trunc(T x); +__generic vector trunc(vector x); +__generic matrix trunc(matrix x); // Shader model 6.0 stuff -__intrinsic_op uint GlobalOrderedCountIncrement(uint countToAppendForThisLane); +uint GlobalOrderedCountIncrement(uint countToAppendForThisLane); -__generic __intrinsic_op T QuadReadLaneAt(T sourceValue, int quadLaneID); -__generic __intrinsic_op vector QuadReadLaneAt(vector sourceValue, int quadLaneID); -__generic __intrinsic_op matrix QuadReadLaneAt(matrix sourceValue, int quadLaneID); +__generic T QuadReadLaneAt(T sourceValue, int quadLaneID); +__generic vector QuadReadLaneAt(vector sourceValue, int quadLaneID); +__generic matrix QuadReadLaneAt(matrix sourceValue, int quadLaneID); -__generic __intrinsic_op T QuadSwapX(T localValue); -__generic __intrinsic_op vector QuadSwapX(vector localValue); -__generic __intrinsic_op matrix QuadSwapX(matrix localValue); +__generic T QuadSwapX(T localValue); +__generic vector QuadSwapX(vector localValue); +__generic matrix QuadSwapX(matrix localValue); -__generic __intrinsic_op T QuadSwapY(T localValue); -__generic __intrinsic_op vector QuadSwapY(vector localValue); -__generic __intrinsic_op matrix QuadSwapY(matrix localValue); +__generic T QuadSwapY(T localValue); +__generic vector QuadSwapY(vector localValue); +__generic matrix QuadSwapY(matrix localValue); -__generic __intrinsic_op T WaveAllBitAnd(T expr); -__generic __intrinsic_op vector WaveAllBitAnd(vector expr); -__generic __intrinsic_op matrix WaveAllBitAnd(matrix expr); +__generic T WaveAllBitAnd(T expr); +__generic vector WaveAllBitAnd(vector expr); +__generic matrix WaveAllBitAnd(matrix expr); -__generic __intrinsic_op T WaveAllBitOr(T expr); -__generic __intrinsic_op vector WaveAllBitOr(vector expr); -__generic __intrinsic_op matrix WaveAllBitOr(matrix expr); +__generic T WaveAllBitOr(T expr); +__generic vector WaveAllBitOr(vector expr); +__generic matrix WaveAllBitOr(matrix expr); -__generic __intrinsic_op T WaveAllBitXor(T expr); -__generic __intrinsic_op vector WaveAllBitXor(vector expr); -__generic __intrinsic_op matrix WaveAllBitXor(matrix expr); +__generic T WaveAllBitXor(T expr); +__generic vector WaveAllBitXor(vector expr); +__generic matrix WaveAllBitXor(matrix expr); -__generic __intrinsic_op T WaveAllMax(T expr); -__generic __intrinsic_op vector WaveAllMax(vector expr); -__generic __intrinsic_op matrix WaveAllMax(matrix expr); +__generic T WaveAllMax(T expr); +__generic vector WaveAllMax(vector expr); +__generic matrix WaveAllMax(matrix expr); -__generic __intrinsic_op T WaveAllMin(T expr); -__generic __intrinsic_op vector WaveAllMin(vector expr); -__generic __intrinsic_op matrix WaveAllMin(matrix expr); +__generic T WaveAllMin(T expr); +__generic vector WaveAllMin(vector expr); +__generic matrix WaveAllMin(matrix expr); -__generic __intrinsic_op T WaveAllProduct(T expr); -__generic __intrinsic_op vector WaveAllProduct(vector expr); -__generic __intrinsic_op matrix WaveAllProduct(matrix expr); +__generic T WaveAllProduct(T expr); +__generic vector WaveAllProduct(vector expr); +__generic matrix WaveAllProduct(matrix expr); -__generic __intrinsic_op T WaveAllSum(T expr); -__generic __intrinsic_op vector WaveAllSum(vector expr); -__generic __intrinsic_op matrix WaveAllSum(matrix expr); +__generic T WaveAllSum(T expr); +__generic vector WaveAllSum(vector expr); +__generic matrix WaveAllSum(matrix expr); -__intrinsic_op bool WaveAllEqual(bool expr); -__intrinsic_op bool WaveAllTrue(bool expr); -__intrinsic_op bool WaveAnyTrue(bool expr); +bool WaveAllEqual(bool expr); +bool WaveAllTrue(bool expr); +bool WaveAnyTrue(bool expr); uint64_t WaveBallot(bool expr); @@ -1018,21 +1000,21 @@ bool WaveIsHelperLane(); bool WaveOnce(); -__generic __intrinsic_op T WavePrefixProduct(T expr); -__generic __intrinsic_op vector WavePrefixProduct(vector expr); -__generic __intrinsic_op matrix WavePrefixProduct(matrix expr); +__generic T WavePrefixProduct(T expr); +__generic vector WavePrefixProduct(vector expr); +__generic matrix WavePrefixProduct(matrix expr); -__generic __intrinsic_op T WavePrefixSum(T expr); -__generic __intrinsic_op vector WavePrefixSum(vector expr); -__generic __intrinsic_op matrix WavePrefixSum(matrix expr); +__generic T WavePrefixSum(T expr); +__generic vector WavePrefixSum(vector expr); +__generic matrix WavePrefixSum(matrix expr); -__generic __intrinsic_op T WaveReadFirstLane(T expr); -__generic __intrinsic_op vector WaveReadFirstLane(vector expr); -__generic __intrinsic_op matrix WaveReadFirstLane(matrix expr); +__generic T WaveReadFirstLane(T expr); +__generic vector WaveReadFirstLane(vector expr); +__generic matrix WaveReadFirstLane(matrix expr); -__generic __intrinsic_op T WaveReadLaneAt(T expr, int laneIndex); -__generic __intrinsic_op vector WaveReadLaneAt(vector expr, int laneIndex); -__generic __intrinsic_op matrix WaveReadLaneAt(matrix expr, int laneIndex); +__generic T WaveReadLaneAt(T expr, int laneIndex); +__generic vector WaveReadLaneAt(vector expr, int laneIndex); +__generic matrix WaveReadLaneAt(matrix expr, int laneIndex); // `typedef`s to help with the fact that HLSL has been sorta-kinda case insensitive at various points typedef Texture2D texture2D; @@ -1092,15 +1074,15 @@ for (int aa = 0; aa < kBaseBufferAccessLevelCount; ++aa) sb << kBaseBufferAccessLevels[aa].name; sb << "Buffer {\n"; - sb << "__intrinsic_op void GetDimensions(out uint dim);\n"; + sb << "void GetDimensions(out uint dim);\n"; sb << "__target_intrinsic(glsl, \"texelFetch($$P, $0)$$z\")\n"; - sb << "__intrinsic_op T Load(int location);\n"; + sb << "T Load(int location);\n"; - sb << "__intrinsic_op T Load(int location, out uint status);\n"; + sb << "T Load(int location, out uint status);\n"; sb << "__target_intrinsic(glsl, \"texelFetch($$P, int($0))$$z\")\n"; - sb << "__intrinsic_op __subscript(uint index) -> T"; + sb << "__subscript(uint index) -> T"; if (kBaseBufferAccessLevels[aa].access != SLANG_RESOURCE_ACCESS_READ) { diff --git a/source/slang/hlsl.meta.slang.h b/source/slang/hlsl.meta.slang.h index dfbdbe57b..c9ccfcc81 100644 --- a/source/slang/hlsl.meta.slang.h +++ b/source/slang/hlsl.meta.slang.h @@ -4,29 +4,29 @@ sb << "typedef uint UINT;\n"; sb << "\n"; sb << "__generic __magic_type(HLSLAppendStructuredBufferType) struct AppendStructuredBuffer\n"; sb << "{\n"; -sb << " __intrinsic_op void Append(T value);\n"; +sb << " void Append(T value);\n"; sb << "\n"; -sb << " __intrinsic_op void GetDimensions(\n"; +sb << " void GetDimensions(\n"; sb << " out uint numStructs,\n"; sb << " out uint stride);\n"; sb << "};\n"; sb << "\n"; sb << "__magic_type(HLSLByteAddressBufferType) struct ByteAddressBuffer\n"; sb << "{\n"; -sb << " __intrinsic_op void GetDimensions(\n"; +sb << " void GetDimensions(\n"; sb << " out uint dim);\n"; sb << "\n"; -sb << " __intrinsic_op uint Load(int location);\n"; -sb << " __intrinsic_op uint Load(int location, out uint status);\n"; +sb << " uint Load(int location);\n"; +sb << " uint Load(int location, out uint status);\n"; sb << "\n"; -sb << " __intrinsic_op uint2 Load2(int location);\n"; -sb << " __intrinsic_op uint2 Load2(int location, out uint status);\n"; +sb << " uint2 Load2(int location);\n"; +sb << " uint2 Load2(int location, out uint status);\n"; sb << "\n"; -sb << " __intrinsic_op uint3 Load3(int location);\n"; -sb << " __intrinsic_op uint3 Load3(int location, out uint status);\n"; +sb << " uint3 Load3(int location);\n"; +sb << " uint3 Load3(int location, out uint status);\n"; sb << "\n"; -sb << " __intrinsic_op uint4 Load4(int location);\n"; -sb << " __intrinsic_op uint4 Load4(int location, out uint status);\n"; +sb << " uint4 Load4(int location);\n"; +sb << " uint4 Load4(int location, out uint status);\n"; sb << "};\n"; sb << "\n"; sb << "__generic\n"; @@ -38,12 +38,12 @@ sb << "__intrinsic_type("; sb << ")\n"; sb << "struct StructuredBuffer\n"; sb << "{\n"; -sb << " __intrinsic_op void GetDimensions(\n"; +sb << " void GetDimensions(\n"; sb << " out uint numStructs,\n"; sb << " out uint stride);\n"; sb << "\n"; -sb << " __intrinsic_op T Load(int location);\n"; -sb << " __intrinsic_op T Load(int location, out uint status);\n"; +sb << " T Load(int location);\n"; +sb << " T Load(int location, out uint status);\n"; sb << "\n"; sb << " __intrinsic_op(bufferLoad)\n"; sb << " __subscript(uint index) -> T;\n"; @@ -51,21 +51,21 @@ sb << "};\n"; sb << "\n"; sb << "__generic __magic_type(HLSLConsumeStructuredBufferType) struct ConsumeStructuredBuffer\n"; sb << "{\n"; -sb << " __intrinsic_op T Consume();\n"; +sb << " T Consume();\n"; sb << "\n"; -sb << " __intrinsic_op void GetDimensions(\n"; +sb << " void GetDimensions(\n"; sb << " out uint numStructs,\n"; sb << " out uint stride);\n"; sb << "};\n"; sb << "\n"; sb << "__generic __magic_type(HLSLInputPatchType) struct InputPatch\n"; sb << "{\n"; -sb << " __intrinsic_op __subscript(uint index) -> T;\n"; +sb << " __subscript(uint index) -> T;\n"; sb << "};\n"; sb << "\n"; sb << "__generic __magic_type(HLSLOutputPatchType) struct OutputPatch\n"; sb << "{\n"; -sb << " __intrinsic_op __subscript(uint index) -> T { set; }\n"; +sb << " __subscript(uint index) -> T { set; }\n"; sb << "};\n"; sb << "\n"; sb << "__magic_type(HLSLRWByteAddressBufferType) struct RWByteAddressBuffer\n"; @@ -73,110 +73,110 @@ sb << "{\n"; sb << " // Note(tfoley): supports alll operations from `ByteAddressBuffer`\n"; sb << " // TODO(tfoley): can this be made a sub-type?\n"; sb << "\n"; -sb << " __intrinsic_op void GetDimensions(\n"; +sb << " void GetDimensions(\n"; sb << " out uint dim);\n"; sb << "\n"; -sb << " __intrinsic_op uint Load(int location);\n"; -sb << " __intrinsic_op uint Load(int location, out uint status);\n"; +sb << " uint Load(int location);\n"; +sb << " uint Load(int location, out uint status);\n"; sb << "\n"; -sb << " __intrinsic_op uint2 Load2(int location);\n"; -sb << " __intrinsic_op uint2 Load2(int location, out uint status);\n"; +sb << " uint2 Load2(int location);\n"; +sb << " uint2 Load2(int location, out uint status);\n"; sb << "\n"; -sb << " __intrinsic_op uint3 Load3(int location);\n"; -sb << " __intrinsic_op uint3 Load3(int location, out uint status);\n"; +sb << " uint3 Load3(int location);\n"; +sb << " uint3 Load3(int location, out uint status);\n"; sb << "\n"; -sb << " __intrinsic_op uint4 Load4(int location);\n"; -sb << " __intrinsic_op uint4 Load4(int location, out uint status);\n"; +sb << " uint4 Load4(int location);\n"; +sb << " uint4 Load4(int location, out uint status);\n"; sb << "\n"; sb << " // Added operations:\n"; sb << "\n"; -sb << " __intrinsic_op void InterlockedAdd(\n"; +sb << " void InterlockedAdd(\n"; sb << " UINT dest,\n"; sb << " UINT value,\n"; sb << " out UINT original_value);\n"; -sb << " __intrinsic_op void InterlockedAdd(\n"; +sb << " void InterlockedAdd(\n"; sb << " UINT dest,\n"; sb << " UINT value);\n"; sb << "\n"; -sb << " __intrinsic_op void InterlockedAnd(\n"; +sb << " void InterlockedAnd(\n"; sb << " UINT dest,\n"; sb << " UINT value,\n"; sb << " out UINT original_value);\n"; -sb << " __intrinsic_op void InterlockedAnd(\n"; +sb << " void InterlockedAnd(\n"; sb << " UINT dest,\n"; sb << " UINT value);\n"; sb << "\n"; -sb << " __intrinsic_op void InterlockedCompareExchange(\n"; +sb << " void InterlockedCompareExchange(\n"; sb << " UINT dest,\n"; sb << " UINT compare_value,\n"; sb << " UINT value,\n"; sb << " out UINT original_value);\n"; -sb << " __intrinsic_op void InterlockedCompareExchange(\n"; +sb << " void InterlockedCompareExchange(\n"; sb << " UINT dest,\n"; sb << " UINT compare_value,\n"; sb << " UINT value);\n"; sb << "\n"; -sb << " __intrinsic_op void InterlockedCompareStore(\n"; +sb << " void InterlockedCompareStore(\n"; sb << " UINT dest,\n"; sb << " UINT compare_value,\n"; sb << " UINT value);\n"; -sb << " __intrinsic_op void InterlockedCompareStore(\n"; +sb << " void InterlockedCompareStore(\n"; sb << " UINT dest,\n"; sb << " UINT compare_value);\n"; sb << "\n"; -sb << " __intrinsic_op void InterlockedExchange(\n"; +sb << " void InterlockedExchange(\n"; sb << " UINT dest,\n"; sb << " UINT value,\n"; sb << " out UINT original_value);\n"; -sb << " __intrinsic_op void InterlockedExchange(\n"; +sb << " void InterlockedExchange(\n"; sb << " UINT dest,\n"; sb << " UINT value);\n"; sb << "\n"; -sb << " __intrinsic_op void InterlockedMax(\n"; +sb << " void InterlockedMax(\n"; sb << " UINT dest,\n"; sb << " UINT value,\n"; sb << " out UINT original_value);\n"; -sb << " __intrinsic_op void InterlockedMax(\n"; +sb << " void InterlockedMax(\n"; sb << " UINT dest,\n"; sb << " UINT value);\n"; sb << "\n"; -sb << " __intrinsic_op void InterlockedMin(\n"; +sb << " void InterlockedMin(\n"; sb << " UINT dest,\n"; sb << " UINT value,\n"; sb << " out UINT original_value);\n"; -sb << " __intrinsic_op void InterlockedMin(\n"; +sb << " void InterlockedMin(\n"; sb << " UINT dest,\n"; sb << " UINT value);\n"; sb << "\n"; -sb << " __intrinsic_op void InterlockedOr(\n"; +sb << " void InterlockedOr(\n"; sb << " UINT dest,\n"; sb << " UINT value,\n"; sb << " out UINT original_value);\n"; -sb << " __intrinsic_op void InterlockedOr(\n"; +sb << " void InterlockedOr(\n"; sb << " UINT dest,\n"; sb << " UINT value);\n"; sb << "\n"; -sb << " __intrinsic_op void InterlockedXor(\n"; +sb << " void InterlockedXor(\n"; sb << " UINT dest,\n"; sb << " UINT value,\n"; sb << " out UINT original_value);\n"; -sb << " __intrinsic_op void InterlockedXor(\n"; +sb << " void InterlockedXor(\n"; sb << " UINT dest,\n"; sb << " UINT value);\n"; sb << "\n"; -sb << " __intrinsic_op void Store(\n"; +sb << " void Store(\n"; sb << " uint address,\n"; sb << " uint value);\n"; sb << "\n"; -sb << " __intrinsic_op void Store2(\n"; +sb << " void Store2(\n"; sb << " uint address,\n"; sb << " uint2 value);\n"; sb << "\n"; -sb << " __intrinsic_op void Store3(\n"; +sb << " void Store3(\n"; sb << " uint address,\n"; sb << " uint3 value);\n"; sb << "\n"; -sb << " __intrinsic_op void Store4(\n"; +sb << " void Store4(\n"; sb << " uint address,\n"; sb << " uint4 value);\n"; sb << "};\n"; @@ -190,18 +190,17 @@ sb << "__intrinsic_type("; sb << ")\n"; sb << "struct RWStructuredBuffer\n"; sb << "{\n"; -sb << " __intrinsic_op uint DecrementCounter();\n"; +sb << " uint DecrementCounter();\n"; sb << "\n"; -sb << " __intrinsic_op void GetDimensions(\n"; +sb << " void GetDimensions(\n"; sb << " out uint numStructs,\n"; sb << " out uint stride);\n"; sb << "\n"; -sb << " __intrinsic_op uint IncrementCounter();\n"; +sb << " uint IncrementCounter();\n"; sb << "\n"; -sb << " __intrinsic_op T Load(int location);\n"; -sb << " __intrinsic_op T Load(int location, out uint status);\n"; +sb << " T Load(int location);\n"; +sb << " T Load(int location, out uint status);\n"; sb << "\n"; -sb << "\t__intrinsic_op\n"; sb << "\t__subscript(uint index) -> T\n"; sb << "\t{\n"; sb << "\t\t__intrinsic_op(bufferLoad)\n"; @@ -233,99 +232,96 @@ sb << "\n"; sb << "// Note(tfoley): Trying to systematically add all the HLSL builtins\n"; sb << "\n"; sb << "// Try to terminate the current draw or dispatch call (HLSL SM 4.0)\n"; -sb << "__intrinsic_op void abort();\n"; +sb << "void abort();\n"; sb << "\n"; sb << "// Absolute value (HLSL SM 1.0)\n"; -sb << "__generic __intrinsic_op T abs(T x);\n"; -sb << "__generic __intrinsic_op vector abs(vector x);\n"; -sb << "__generic __intrinsic_op matrix abs(matrix x);\n"; +sb << "__generic T abs(T x);\n"; +sb << "__generic vector abs(vector x);\n"; +sb << "__generic matrix abs(matrix x);\n"; sb << "\n"; sb << "// Inverse cosine (HLSL SM 1.0)\n"; -sb << "__generic __intrinsic_op T acos(T x);\n"; -sb << "__generic __intrinsic_op vector acos(vector x);\n"; -sb << "__generic __intrinsic_op matrix acos(matrix x);\n"; +sb << "__generic T acos(T x);\n"; +sb << "__generic vector acos(vector x);\n"; +sb << "__generic matrix acos(matrix x);\n"; sb << "\n"; sb << "// Test if all components are non-zero (HLSL SM 1.0)\n"; -sb << "__generic __intrinsic_op T all(T x);\n"; -sb << "__generic __intrinsic_op vector all(vector x);\n"; -sb << "__generic __intrinsic_op matrix all(matrix x);\n"; +sb << "__generic T all(T x);\n"; +sb << "__generic vector all(vector x);\n"; +sb << "__generic matrix all(matrix x);\n"; sb << "\n"; sb << "// Barrier for writes to all memory spaces (HLSL SM 5.0)\n"; -sb << "__intrinsic_op void AllMemoryBarrier();\n"; +sb << "void AllMemoryBarrier();\n"; sb << "\n"; sb << "// Thread-group sync and barrier for writes to all memory spaces (HLSL SM 5.0)\n"; -sb << "__intrinsic_op void AllMemoryBarrierWithGroupSync();\n"; +sb << "void AllMemoryBarrierWithGroupSync();\n"; sb << "\n"; sb << "// Test if any components is non-zero (HLSL SM 1.0)\n"; -sb << "__generic __intrinsic_op T any(T x);\n"; -sb << "__generic __intrinsic_op vector any(vector x);\n"; -sb << "__generic __intrinsic_op matrix any(matrix x);\n"; +sb << "__generic T any(T x);\n"; +sb << "__generic vector any(vector x);\n"; +sb << "__generic matrix any(matrix x);\n"; sb << "\n"; sb << "\n"; sb << "// Reinterpret bits as a double (HLSL SM 5.0)\n"; -sb << "__intrinsic_op double asdouble(uint lowbits, uint highbits);\n"; +sb << "double asdouble(uint lowbits, uint highbits);\n"; sb << "\n"; sb << "// Reinterpret bits as a float (HLSL SM 4.0)\n"; -sb << "__intrinsic_op float asfloat( int x);\n"; -sb << "__intrinsic_op float asfloat(uint x);\n"; -sb << "__generic __intrinsic_op vector asfloat(vector< int,N> x);\n"; -sb << "__generic __intrinsic_op vector asfloat(vector x);\n"; -sb << "__generic __intrinsic_op matrix asfloat(matrix< int,N,M> x);\n"; -sb << "__generic __intrinsic_op matrix asfloat(matrix x);\n"; +sb << "float asfloat( int x);\n"; +sb << "float asfloat(uint x);\n"; +sb << "__generic vector asfloat(vector< int,N> x);\n"; +sb << "__generic vector asfloat(vector x);\n"; +sb << "__generic matrix asfloat(matrix< int,N,M> x);\n"; +sb << "__generic matrix asfloat(matrix x);\n"; sb << "\n"; sb << "\n"; sb << "// Inverse sine (HLSL SM 1.0)\n"; -sb << "__generic __intrinsic_op T asin(T x);\n"; -sb << "__generic __intrinsic_op vector asin(vector x);\n"; -sb << "__generic __intrinsic_op matrix asin(matrix x);\n"; +sb << "__generic T asin(T x);\n"; +sb << "__generic vector asin(vector x);\n"; +sb << "__generic matrix asin(matrix x);\n"; sb << "\n"; sb << "// Reinterpret bits as an int (HLSL SM 4.0)\n"; -sb << "__intrinsic_op int asint(float x);\n"; -sb << "__intrinsic_op int asint(uint x);\n"; -sb << "__generic __intrinsic_op vector asint(vector x);\n"; -sb << "__generic __intrinsic_op vector asint(vector x);\n"; -sb << "__generic __intrinsic_op matrix asint(matrix x);\n"; -sb << "__generic __intrinsic_op matrix asint(matrix x);\n"; +sb << "int asint(float x);\n"; +sb << "int asint(uint x);\n"; +sb << "__generic vector asint(vector x);\n"; +sb << "__generic vector asint(vector x);\n"; +sb << "__generic matrix asint(matrix x);\n"; +sb << "__generic matrix asint(matrix x);\n"; sb << "\n"; sb << "// Reinterpret bits of double as a uint (HLSL SM 5.0)\n"; -sb << "__intrinsic_op void asuint(double value, out uint lowbits, out uint highbits);\n"; +sb << "void asuint(double value, out uint lowbits, out uint highbits);\n"; sb << "\n"; sb << "// Reinterpret bits as a uint (HLSL SM 4.0)\n"; -sb << "__intrinsic_op uint asuint(float x);\n"; -sb << "__intrinsic_op uint asuint(int x);\n"; -sb << "__generic __intrinsic_op vector asuint(vector x);\n"; -sb << "__generic __intrinsic_op vector asuint(vector x);\n"; -sb << "__generic __intrinsic_op matrix asuint(matrix x);\n"; -sb << "__generic __intrinsic_op matrix asuint(matrix x);\n"; +sb << "uint asuint(float x);\n"; +sb << "uint asuint(int x);\n"; +sb << "__generic vector asuint(vector x);\n"; +sb << "__generic vector asuint(vector x);\n"; +sb << "__generic matrix asuint(matrix x);\n"; +sb << "__generic matrix asuint(matrix x);\n"; sb << "\n"; sb << "// Inverse tangent (HLSL SM 1.0)\n"; -sb << "__generic __intrinsic_op T atan(T x);\n"; -sb << "__generic __intrinsic_op vector atan(vector x);\n"; -sb << "__generic __intrinsic_op matrix atan(matrix x);\n"; +sb << "__generic T atan(T x);\n"; +sb << "__generic vector atan(vector x);\n"; +sb << "__generic matrix atan(matrix x);\n"; sb << "\n"; sb << "__generic\n"; sb << "__target_intrinsic(glsl,\"atan($0,$1)\")\n"; -sb << "__intrinsic_op\n"; sb << "T atan2(T y, T x);\n"; sb << "\n"; sb << "__generic\n"; sb << "__target_intrinsic(glsl,\"atan($0,$1)\")\n"; -sb << "__intrinsic_op\n"; sb << "vector atan2(vector y, vector x);\n"; sb << "\n"; sb << "__generic\n"; sb << "__target_intrinsic(glsl,\"atan($0,$1)\")\n"; -sb << "__intrinsic_op\n"; sb << "matrix atan2(matrix y, matrix x);\n"; sb << "\n"; sb << "// Ceiling (HLSL SM 1.0)\n"; -sb << "__generic __intrinsic_op T ceil(T x);\n"; -sb << "__generic __intrinsic_op vector ceil(vector x);\n"; -sb << "__generic __intrinsic_op matrix ceil(matrix x);\n"; +sb << "__generic T ceil(T x);\n"; +sb << "__generic vector ceil(vector x);\n"; +sb << "__generic matrix ceil(matrix x);\n"; sb << "\n"; sb << "\n"; sb << "// Check access status to tiled resource\n"; -sb << "__intrinsic_op bool CheckAccessFullyMapped(uint status);\n"; +sb << "bool CheckAccessFullyMapped(uint status);\n"; sb << "\n"; sb << "// Clamp (HLSL SM 1.0)\n"; sb << "__generic T clamp(T x, T min, T max);\n"; @@ -333,9 +329,9 @@ sb << "__generic vector clamp(vec sb << "__generic matrix clamp(matrix x, matrix min, matrix max);\n"; sb << "\n"; sb << "// Clip (discard) fragment conditionally\n"; -sb << "__generic __intrinsic_op void clip(T x);\n"; -sb << "__generic __intrinsic_op void clip(vector x);\n"; -sb << "__generic __intrinsic_op void clip(matrix x);\n"; +sb << "__generic void clip(T x);\n"; +sb << "__generic void clip(vector x);\n"; +sb << "__generic void clip(matrix x);\n"; sb << "\n"; sb << "// Cosine\n"; sb << "__generic T cos(T x);\n"; @@ -343,360 +339,348 @@ sb << "__generic vector cos(ve sb << "__generic matrix cos(matrix x);\n"; sb << "\n"; sb << "// Hyperbolic cosine\n"; -sb << "__generic __intrinsic_op T cosh(T x);\n"; -sb << "__generic __intrinsic_op vector cosh(vector x);\n"; -sb << "__generic __intrinsic_op matrix cosh(matrix x);\n"; +sb << "__generic T cosh(T x);\n"; +sb << "__generic vector cosh(vector x);\n"; +sb << "__generic matrix cosh(matrix x);\n"; sb << "\n"; sb << "// Population count\n"; -sb << "__intrinsic_op uint countbits(uint value);\n"; +sb << "uint countbits(uint value);\n"; sb << "\n"; sb << "// Cross product\n"; -sb << "__generic __intrinsic_op vector cross(vector x, vector y);\n"; +sb << "__generic vector cross(vector x, vector y);\n"; sb << "\n"; sb << "// Convert encoded color\n"; -sb << "__intrinsic_op int4 D3DCOLORtoUBYTE4(float4 x);\n"; +sb << "int4 D3DCOLORtoUBYTE4(float4 x);\n"; sb << "\n"; sb << "// Partial-difference derivatives\n"; sb << "__generic\n"; sb << "__target_intrinsic(glsl, dFdx)\n"; -sb << "__intrinsic_op\n"; sb << "T ddx(T x);\n"; +sb << "\n"; sb << "__generic\n"; sb << "__target_intrinsic(glsl, dFdx)\n"; -sb << "__intrinsic_op\n"; sb << "vector ddx(vector x);\n"; +sb << "\n"; sb << "__generic\n"; sb << "__target_intrinsic(glsl, dFdx)\n"; -sb << "__intrinsic_op\n"; sb << "matrix ddx(matrix x);\n"; sb << "\n"; sb << "__generic\n"; sb << "__glsl_extension(GL_ARB_derivative_control)\n"; sb << "__target_intrinsic(glsl, dFdxCoarse)\n"; -sb << "__intrinsic_op\n"; sb << "T ddx_coarse(T x);\n"; +sb << "\n"; sb << "__generic\n"; sb << "__glsl_extension(GL_ARB_derivative_control)\n"; sb << "__target_intrinsic(glsl, dFdxCoarse)\n"; -sb << "__intrinsic_op\n"; sb << "vector ddx_coarse(vector x);\n"; +sb << "\n"; sb << "__generic\n"; sb << "__glsl_extension(GL_ARB_derivative_control)\n"; sb << "__target_intrinsic(glsl, dFdxCoarse)\n"; -sb << "__intrinsic_op\n"; sb << "matrix ddx_coarse(matrix x);\n"; sb << "\n"; sb << "__generic\n"; sb << "__glsl_extension(GL_ARB_derivative_control)\n"; sb << "__target_intrinsic(glsl, dFdxFine)\n"; -sb << "__intrinsic_op\n"; sb << "T ddx_fine(T x);\n"; +sb << "\n"; sb << "__generic\n"; sb << "__glsl_extension(GL_ARB_derivative_control)\n"; sb << "__target_intrinsic(glsl, dFdxFine)\n"; -sb << "__intrinsic_op\n"; sb << "vector ddx_fine(vector x);\n"; +sb << "\n"; sb << "__generic\n"; sb << "__glsl_extension(GL_ARB_derivative_control)\n"; sb << "__target_intrinsic(glsl, dFdxFine)\n"; -sb << "__intrinsic_op\n"; sb << "matrix ddx_fine(matrix x);\n"; sb << "\n"; sb << "__generic\n"; sb << "__target_intrinsic(glsl, dFdy)\n"; -sb << "__intrinsic_op\n"; sb << "T ddy(T x);\n"; +sb << "\n"; sb << "__generic\n"; sb << "__target_intrinsic(glsl, dFdy)\n"; -sb << "__intrinsic_op\n"; sb << "vector ddy(vector x);\n"; +sb << "\n"; sb << "__generic\n"; sb << "__target_intrinsic(glsl, dFdy)\n"; -sb << "__intrinsic_op\n"; sb << " matrix ddy(matrix x);\n"; sb << "\n"; sb << "__generic\n"; sb << "__glsl_extension(GL_ARB_derivative_control)\n"; sb << "__target_intrinsic(glsl, dFdyCoarse)\n"; -sb << "__intrinsic_op\n"; sb << "T ddy_coarse(T x);\n"; +sb << "\n"; sb << "__generic\n"; sb << "__glsl_extension(GL_ARB_derivative_control)\n"; sb << "__target_intrinsic(glsl, dFdyCoarse)\n"; -sb << "__intrinsic_op\n"; sb << "vector ddy_coarse(vector x);\n"; +sb << "\n"; sb << "__generic\n"; sb << "__glsl_extension(GL_ARB_derivative_control)\n"; sb << "__target_intrinsic(glsl, dFdyCoarse)\n"; -sb << "__intrinsic_op\n"; sb << "matrix ddy_coarse(matrix x);\n"; sb << "\n"; sb << "__generic\n"; sb << "__glsl_extension(GL_ARB_derivative_control)\n"; sb << "__target_intrinsic(glsl, dFdyFine)\n"; -sb << "__intrinsic_op\n"; sb << "T ddy_fine(T x);\n"; +sb << "\n"; sb << "__generic\n"; sb << "__glsl_extension(GL_ARB_derivative_control)\n"; sb << "__target_intrinsic(glsl, dFdyFine)\n"; -sb << "__intrinsic_op\n"; sb << "vector ddy_fine(vector x);\n"; +sb << "\n"; sb << "__generic\n"; sb << "__glsl_extension(GL_ARB_derivative_control)\n"; sb << "__target_intrinsic(glsl, dFdyFine)\n"; -sb << "__intrinsic_op\n"; sb << "matrix ddy_fine(matrix x);\n"; sb << "\n"; sb << "\n"; sb << "// Radians to degrees\n"; -sb << "__generic __intrinsic_op T degrees(T x);\n"; -sb << "__generic __intrinsic_op vector degrees(vector x);\n"; -sb << "__generic __intrinsic_op matrix degrees(matrix x);\n"; +sb << "__generic T degrees(T x);\n"; +sb << "__generic vector degrees(vector x);\n"; +sb << "__generic matrix degrees(matrix x);\n"; sb << "\n"; sb << "// Matrix determinant\n"; sb << "\n"; -sb << "__generic __intrinsic_op T determinant(matrix m);\n"; +sb << "__generic T determinant(matrix m);\n"; sb << "\n"; sb << "// Barrier for device memory\n"; -sb << "__intrinsic_op void DeviceMemoryBarrier();\n"; -sb << "__intrinsic_op void DeviceMemoryBarrierWithGroupSync();\n"; +sb << "void DeviceMemoryBarrier();\n"; +sb << "void DeviceMemoryBarrierWithGroupSync();\n"; sb << "\n"; sb << "// Vector distance\n"; sb << "\n"; -sb << "__generic __intrinsic_op T distance(vector x, vector y);\n"; +sb << "__generic T distance(vector x, vector y);\n"; sb << "\n"; sb << "// Vector dot product\n"; sb << "\n"; -sb << "__generic __intrinsic_op T dot(vector x, vector y);\n"; +sb << "__generic T dot(vector x, vector y);\n"; sb << "\n"; sb << "// Helper for computing distance terms for lighting (obsolete)\n"; sb << "\n"; -sb << "__generic __intrinsic_op vector dst(vector x, vector y);\n"; +sb << "__generic vector dst(vector x, vector y);\n"; sb << "\n"; sb << "// Error message\n"; sb << "\n"; -sb << "// __intrinsic_op void errorf( string format, ... );\n"; +sb << "// void errorf( string format, ... );\n"; sb << "\n"; sb << "// Attribute evaluation\n"; sb << "\n"; -sb << "__generic __intrinsic_op T EvaluateAttributeAtCentroid(T x);\n"; -sb << "__generic __intrinsic_op vector EvaluateAttributeAtCentroid(vector x);\n"; -sb << "__generic __intrinsic_op matrix EvaluateAttributeAtCentroid(matrix x);\n"; +sb << "__generic T EvaluateAttributeAtCentroid(T x);\n"; +sb << "__generic vector EvaluateAttributeAtCentroid(vector x);\n"; +sb << "__generic matrix EvaluateAttributeAtCentroid(matrix x);\n"; sb << "\n"; -sb << "__generic __intrinsic_op T EvaluateAttributeAtSample(T x, uint sampleindex);\n"; -sb << "__generic __intrinsic_op vector EvaluateAttributeAtSample(vector x, uint sampleindex);\n"; -sb << "__generic __intrinsic_op matrix EvaluateAttributeAtSample(matrix x, uint sampleindex);\n"; +sb << "__generic T EvaluateAttributeAtSample(T x, uint sampleindex);\n"; +sb << "__generic vector EvaluateAttributeAtSample(vector x, uint sampleindex);\n"; +sb << "__generic matrix EvaluateAttributeAtSample(matrix x, uint sampleindex);\n"; sb << "\n"; -sb << "__generic __intrinsic_op T EvaluateAttributeSnapped(T x, int2 offset);\n"; -sb << "__generic __intrinsic_op vector EvaluateAttributeSnapped(vector x, int2 offset);\n"; -sb << "__generic __intrinsic_op matrix EvaluateAttributeSnapped(matrix x, int2 offset);\n"; +sb << "__generic T EvaluateAttributeSnapped(T x, int2 offset);\n"; +sb << "__generic vector EvaluateAttributeSnapped(vector x, int2 offset);\n"; +sb << "__generic matrix EvaluateAttributeSnapped(matrix x, int2 offset);\n"; sb << "\n"; sb << "// Base-e exponent\n"; -sb << "__generic __intrinsic_op T exp(T x);\n"; -sb << "__generic __intrinsic_op vector exp(vector x);\n"; -sb << "__generic __intrinsic_op matrix exp(matrix x);\n"; +sb << "__generic T exp(T x);\n"; +sb << "__generic vector exp(vector x);\n"; +sb << "__generic matrix exp(matrix x);\n"; sb << "\n"; sb << "// Base-2 exponent\n"; -sb << "__generic __intrinsic_op T exp2(T x);\n"; -sb << "__generic __intrinsic_op vector exp2(vector x);\n"; -sb << "__generic __intrinsic_op matrix exp2(matrix x);\n"; +sb << "__generic T exp2(T x);\n"; +sb << "__generic vector exp2(vector x);\n"; +sb << "__generic matrix exp2(matrix x);\n"; sb << "\n"; sb << "// Convert 16-bit float stored in low bits of integer\n"; -sb << "__intrinsic_op float f16tof32(uint value);\n"; -sb << "__generic __intrinsic_op vector f16tof32(vector value);\n"; +sb << "float f16tof32(uint value);\n"; +sb << "__generic vector f16tof32(vector value);\n"; sb << "\n"; sb << "// Convert to 16-bit float stored in low bits of integer\n"; -sb << "__intrinsic_op uint f32tof16(float value);\n"; -sb << "__generic __intrinsic_op vector f32tof16(vector value);\n"; +sb << "uint f32tof16(float value);\n"; +sb << "__generic vector f32tof16(vector value);\n"; sb << "\n"; sb << "// Flip surface normal to face forward, if needed\n"; -sb << "__generic __intrinsic_op vector faceforward(vector n, vector i, vector ng);\n"; +sb << "__generic vector faceforward(vector n, vector i, vector ng);\n"; sb << "\n"; sb << "// Find first set bit starting at high bit and working down\n"; -sb << "__intrinsic_op int firstbithigh(int value);\n"; -sb << "__generic __intrinsic_op vector firstbithigh(vector value);\n"; +sb << "int firstbithigh(int value);\n"; +sb << "__generic vector firstbithigh(vector value);\n"; sb << "\n"; -sb << "__intrinsic_op uint firstbithigh(uint value);\n"; -sb << "__generic __intrinsic_op vector firstbithigh(vector value);\n"; +sb << "uint firstbithigh(uint value);\n"; +sb << "__generic vector firstbithigh(vector value);\n"; sb << "\n"; sb << "// Find first set bit starting at low bit and working up\n"; -sb << "__intrinsic_op int firstbitlow(int value);\n"; -sb << "__generic __intrinsic_op vector firstbitlow(vector value);\n"; +sb << "int firstbitlow(int value);\n"; +sb << "__generic vector firstbitlow(vector value);\n"; sb << "\n"; -sb << "__intrinsic_op uint firstbitlow(uint value);\n"; -sb << "__generic __intrinsic_op vector firstbitlow(vector value);\n"; +sb << "uint firstbitlow(uint value);\n"; +sb << "__generic vector firstbitlow(vector value);\n"; sb << "\n"; sb << "// Floor (HLSL SM 1.0)\n"; -sb << "__generic __intrinsic_op T floor(T x);\n"; -sb << "__generic __intrinsic_op vector floor(vector x);\n"; -sb << "__generic __intrinsic_op matrix floor(matrix x);\n"; +sb << "__generic T floor(T x);\n"; +sb << "__generic vector floor(vector x);\n"; +sb << "__generic matrix floor(matrix x);\n"; sb << "\n"; sb << "// Fused multiply-add for doubles\n"; -sb << "__intrinsic_op double fma(double a, double b, double c);\n"; -sb << "__generic __intrinsic_op vector fma(vector a, vector b, vector c);\n"; -sb << "__generic __intrinsic_op matrix fma(matrix a, matrix b, matrix c);\n"; +sb << "double fma(double a, double b, double c);\n"; +sb << "__generic vector fma(vector a, vector b, vector c);\n"; +sb << "__generic matrix fma(matrix a, matrix b, matrix c);\n"; sb << "\n"; sb << "// Floating point remainder of x/y\n"; -sb << "__generic __intrinsic_op T fmod(T x, T y);\n"; -sb << "__generic __intrinsic_op vector fmod(vector x, vector y);\n"; -sb << "__generic __intrinsic_op matrix fmod(matrix x, matrix y);\n"; +sb << "__generic T fmod(T x, T y);\n"; +sb << "__generic vector fmod(vector x, vector y);\n"; +sb << "__generic matrix fmod(matrix x, matrix y);\n"; sb << "\n"; sb << "// Fractional part\n"; sb << "__generic\n"; sb << "__target_intrinsic(glsl, fract)\n"; -sb << "__intrinsic_op\n"; sb << "T frac(T x);\n"; sb << "\n"; sb << "__generic\n"; sb << "__target_intrinsic(glsl, fract)\n"; -sb << "__intrinsic_op\n"; sb << "vector frac(vector x);\n"; sb << "\n"; sb << "__generic\n"; sb << "__target_intrinsic(glsl, fract)\n"; -sb << "__intrinsic_op\n"; sb << "matrix frac(matrix x);\n"; sb << "\n"; sb << "// Split float into mantissa and exponent\n"; -sb << "__generic __intrinsic_op T frexp(T x, out T exp);\n"; -sb << "__generic __intrinsic_op vector frexp(vector x, out vector exp);\n"; -sb << "__generic __intrinsic_op matrix frexp(matrix x, out matrix exp);\n"; +sb << "__generic T frexp(T x, out T exp);\n"; +sb << "__generic vector frexp(vector x, out vector exp);\n"; +sb << "__generic matrix frexp(matrix x, out matrix exp);\n"; sb << "\n"; sb << "// Texture filter width\n"; -sb << "__generic __intrinsic_op T fwidth(T x);\n"; -sb << "__generic __intrinsic_op vector fwidth(vector x);\n"; -sb << "__generic __intrinsic_op matrix fwidth(matrix x);\n"; +sb << "__generic T fwidth(T x);\n"; +sb << "__generic vector fwidth(vector x);\n"; +sb << "__generic matrix fwidth(matrix x);\n"; sb << "\n"; sb << "// Get number of samples in render target\n"; -sb << "__intrinsic_op uint GetRenderTargetSampleCount();\n"; +sb << "uint GetRenderTargetSampleCount();\n"; sb << "\n"; sb << "// Get position of given sample\n"; -sb << "__intrinsic_op float2 GetRenderTargetSamplePosition(int Index);\n"; +sb << "float2 GetRenderTargetSamplePosition(int Index);\n"; sb << "\n"; sb << "// Group memory barrier\n"; -sb << "__intrinsic_op void GroupMemoryBarrier();\n"; -sb << "__intrinsic_op void GroupMemoryBarrierWithGroupSync();\n"; +sb << "void GroupMemoryBarrier();\n"; +sb << "void GroupMemoryBarrierWithGroupSync();\n"; sb << "\n"; sb << "// Atomics\n"; -sb << "__intrinsic_op void InterlockedAdd(in out int dest, int value, out int original_value);\n"; -sb << "__intrinsic_op void InterlockedAdd(in out uint dest, uint value, out uint original_value);\n"; +sb << "void InterlockedAdd(in out int dest, int value, out int original_value);\n"; +sb << "void InterlockedAdd(in out uint dest, uint value, out uint original_value);\n"; sb << "\n"; -sb << "__intrinsic_op void InterlockedAnd(in out int dest, int value, out int original_value);\n"; -sb << "__intrinsic_op void InterlockedAnd(in out uint dest, uint value, out uint original_value);\n"; +sb << "void InterlockedAnd(in out int dest, int value, out int original_value);\n"; +sb << "void InterlockedAnd(in out uint dest, uint value, out uint original_value);\n"; sb << "\n"; -sb << "__intrinsic_op void InterlockedCompareExchange(in out int dest, int compare_value, int value, out int original_value);\n"; -sb << "__intrinsic_op void InterlockedCompareExchange(in out uint dest, uint compare_value, uint value, out uint original_value);\n"; +sb << "void InterlockedCompareExchange(in out int dest, int compare_value, int value, out int original_value);\n"; +sb << "void InterlockedCompareExchange(in out uint dest, uint compare_value, uint value, out uint original_value);\n"; sb << "\n"; -sb << "__intrinsic_op void InterlockedCompareStore(in out int dest, int compare_value, int value);\n"; -sb << "__intrinsic_op void InterlockedCompareStore(in out uint dest, uint compare_value, uint value);\n"; +sb << "void InterlockedCompareStore(in out int dest, int compare_value, int value);\n"; +sb << "void InterlockedCompareStore(in out uint dest, uint compare_value, uint value);\n"; sb << "\n"; -sb << "__intrinsic_op void InterlockedExchange(in out int dest, int value, out int original_value);\n"; -sb << "__intrinsic_op void InterlockedExchange(in out uint dest, uint value, out uint original_value);\n"; +sb << "void InterlockedExchange(in out int dest, int value, out int original_value);\n"; +sb << "void InterlockedExchange(in out uint dest, uint value, out uint original_value);\n"; sb << "\n"; -sb << "__intrinsic_op void InterlockedMax(in out int dest, int value, out int original_value);\n"; -sb << "__intrinsic_op void InterlockedMax(in out uint dest, uint value, out uint original_value);\n"; +sb << "void InterlockedMax(in out int dest, int value, out int original_value);\n"; +sb << "void InterlockedMax(in out uint dest, uint value, out uint original_value);\n"; sb << "\n"; -sb << "__intrinsic_op void InterlockedMin(in out int dest, int value, out int original_value);\n"; -sb << "__intrinsic_op void InterlockedMin(in out uint dest, uint value, out uint original_value);\n"; +sb << "void InterlockedMin(in out int dest, int value, out int original_value);\n"; +sb << "void InterlockedMin(in out uint dest, uint value, out uint original_value);\n"; sb << "\n"; -sb << "__intrinsic_op void InterlockedOr(in out int dest, int value, out int original_value);\n"; -sb << "__intrinsic_op void InterlockedOr(in out uint dest, uint value, out uint original_value);\n"; +sb << "void InterlockedOr(in out int dest, int value, out int original_value);\n"; +sb << "void InterlockedOr(in out uint dest, uint value, out uint original_value);\n"; sb << "\n"; -sb << "__intrinsic_op void InterlockedXor(in out int dest, int value, out int original_value);\n"; -sb << "__intrinsic_op void InterlockedXor(in out uint dest, uint value, out uint original_value);\n"; +sb << "void InterlockedXor(in out int dest, int value, out int original_value);\n"; +sb << "void InterlockedXor(in out uint dest, uint value, out uint original_value);\n"; sb << "\n"; sb << "// Is floating-point value finite?\n"; -sb << "__generic __intrinsic_op bool isfinite(T x);\n"; -sb << "__generic __intrinsic_op vector isfinite(vector x);\n"; -sb << "__generic __intrinsic_op matrix isfinite(matrix x);\n"; +sb << "__generic bool isfinite(T x);\n"; +sb << "__generic vector isfinite(vector x);\n"; +sb << "__generic matrix isfinite(matrix x);\n"; sb << "\n"; sb << "// Is floating-point value infinite?\n"; -sb << "__generic __intrinsic_op bool isinf(T x);\n"; -sb << "__generic __intrinsic_op vector isinf(vector x);\n"; -sb << "__generic __intrinsic_op matrix isinf(matrix x);\n"; +sb << "__generic bool isinf(T x);\n"; +sb << "__generic vector isinf(vector x);\n"; +sb << "__generic matrix isinf(matrix x);\n"; sb << "\n"; sb << "// Is floating-point value not-a-number?\n"; -sb << "__generic __intrinsic_op bool isnan(T x);\n"; -sb << "__generic __intrinsic_op vector isnan(vector x);\n"; -sb << "__generic __intrinsic_op matrix isnan(matrix x);\n"; +sb << "__generic bool isnan(T x);\n"; +sb << "__generic vector isnan(vector x);\n"; +sb << "__generic matrix isnan(matrix x);\n"; sb << "\n"; sb << "// Construct float from mantissa and exponent\n"; -sb << "__generic __intrinsic_op T ldexp(T x, T exp);\n"; -sb << "__generic __intrinsic_op vector ldexp(vector x, vector exp);\n"; -sb << "__generic __intrinsic_op matrix ldexp(matrix x, matrix exp);\n"; +sb << "__generic T ldexp(T x, T exp);\n"; +sb << "__generic vector ldexp(vector x, vector exp);\n"; +sb << "__generic matrix ldexp(matrix x, matrix exp);\n"; sb << "\n"; sb << "// Vector length\n"; -sb << "__generic __intrinsic_op T length(vector x);\n"; +sb << "__generic T length(vector x);\n"; sb << "\n"; sb << "// Linear interpolation\n"; sb << "__generic\n"; sb << "__target_intrinsic(glsl, mix)\n"; -sb << "__intrinsic_op\n"; sb << "T lerp(T x, T y, T s);\n"; sb << "\n"; sb << "__generic\n"; sb << "__target_intrinsic(glsl, mix)\n"; -sb << "__intrinsic_op\n"; sb << "vector lerp(vector x, vector y, vector s);\n"; sb << "\n"; sb << "__generic\n"; sb << "__target_intrinsic(glsl, mix)\n"; -sb << "__intrinsic_op\n"; sb << "matrix lerp(matrix x, matrix y, matrix s);\n"; sb << "\n"; sb << "// Legacy lighting function (obsolete)\n"; -sb << "__intrinsic_op float4 lit(float n_dot_l, float n_dot_h, float m);\n"; +sb << "float4 lit(float n_dot_l, float n_dot_h, float m);\n"; sb << "\n"; sb << "// Base-e logarithm\n"; -sb << "__generic __intrinsic_op T log(T x);\n"; -sb << "__generic __intrinsic_op vector log(vector x);\n"; -sb << "__generic __intrinsic_op matrix log(matrix x);\n"; +sb << "__generic T log(T x);\n"; +sb << "__generic vector log(vector x);\n"; +sb << "__generic matrix log(matrix x);\n"; sb << "\n"; sb << "// Base-10 logarithm\n"; -sb << "__generic __intrinsic_op T log10(T x);\n"; -sb << "__generic __intrinsic_op vector log10(vector x);\n"; -sb << "__generic __intrinsic_op matrix log10(matrix x);\n"; +sb << "__generic T log10(T x);\n"; +sb << "__generic vector log10(vector x);\n"; +sb << "__generic matrix log10(matrix x);\n"; sb << "\n"; sb << "// Base-2 logarithm\n"; -sb << "__generic __intrinsic_op T log2(T x);\n"; -sb << "__generic __intrinsic_op vector log2(vector x);\n"; -sb << "__generic __intrinsic_op matrix log2(matrix x);\n"; +sb << "__generic T log2(T x);\n"; +sb << "__generic vector log2(vector x);\n"; +sb << "__generic matrix log2(matrix x);\n"; sb << "\n"; sb << "// multiply-add\n"; -sb << "__generic __intrinsic_op T mad(T mvalue, T avalue, T bvalue);\n"; -sb << "__generic __intrinsic_op vector mad(vector mvalue, vector avalue, vector bvalue);\n"; -sb << "__generic __intrinsic_op matrix mad(matrix mvalue, matrix avalue, matrix bvalue);\n"; +sb << "__generic T mad(T mvalue, T avalue, T bvalue);\n"; +sb << "__generic vector mad(vector mvalue, vector avalue, vector bvalue);\n"; +sb << "__generic matrix mad(matrix mvalue, matrix avalue, matrix bvalue);\n"; sb << "\n"; sb << "// maximum\n"; -sb << "__generic __intrinsic_op T max(T x, T y);\n"; -sb << "__generic __intrinsic_op vector max(vector x, vector y);\n"; -sb << "__generic __intrinsic_op matrix max(matrix x, matrix y);\n"; +sb << "__generic T max(T x, T y);\n"; +sb << "__generic vector max(vector x, vector y);\n"; +sb << "__generic matrix max(matrix x, matrix y);\n"; sb << "\n"; sb << "// minimum\n"; -sb << "__generic __intrinsic_op T min(T x, T y);\n"; -sb << "__generic __intrinsic_op vector min(vector x, vector y);\n"; -sb << "__generic __intrinsic_op matrix min(matrix x, matrix y);\n"; +sb << "__generic T min(T x, T y);\n"; +sb << "__generic vector min(vector x, vector y);\n"; +sb << "__generic matrix min(matrix x, matrix y);\n"; sb << "\n"; sb << "// split into integer and fractional parts (both with same sign)\n"; -sb << "__generic __intrinsic_op T modf(T x, out T ip);\n"; -sb << "__generic __intrinsic_op vector modf(vector x, out vector ip);\n"; -sb << "__generic __intrinsic_op matrix modf(matrix x, out matrix ip);\n"; +sb << "__generic T modf(T x, out T ip);\n"; +sb << "__generic vector modf(vector x, out vector ip);\n"; +sb << "__generic matrix modf(matrix x, out matrix ip);\n"; sb << "\n"; sb << "// msad4 (whatever that is)\n"; -sb << "__intrinsic_op uint4 msad4(uint reference, uint2 source, uint4 accum);\n"; +sb << "uint4 msad4(uint reference, uint2 source, uint4 accum);\n"; sb << "\n"; sb << "// General inner products\n"; sb << "\n"; sb << "// scalar-scalar\n"; -sb << "__generic __intrinsic_op T mul(T x, T y);\n"; +sb << "__generic T mul(T x, T y);\n"; sb << "\n"; sb << "// scalar-vector and vector-scalar\n"; -sb << "__generic __intrinsic_op vector mul(vector x, T y);\n"; -sb << "__generic __intrinsic_op vector mul(T x, vector y);\n"; +sb << "__generic vector mul(vector x, T y);\n"; +sb << "__generic vector mul(T x, vector y);\n"; sb << "\n"; sb << "// scalar-matrix and matrix-scalar\n"; -sb << "__generic __intrinsic_op matrix mul(matrix x, T y);\n"; -sb << "__generic __intrinsic_op matrix mul(T x, matrix y);\n"; +sb << "__generic matrix mul(matrix x, T y);\n"; +sb << "__generic matrix mul(T x, matrix y);\n"; sb << "\n"; sb << "// vector-vector (dot product)\n"; sb << "__generic __intrinsic_op(dot) T mul(vector x, vector y);\n"; @@ -711,86 +695,86 @@ sb << "// matrix-matrix\n"; sb << "__generic __intrinsic_op(mulMatrixMatrix) matrix mul(matrix x, matrix y);\n"; sb << "\n"; sb << "// noise (deprecated)\n"; -sb << "__intrinsic_op float noise(float x);\n"; -sb << "__generic __intrinsic_op float noise(vector x);\n"; +sb << "float noise(float x);\n"; +sb << "__generic float noise(vector x);\n"; sb << "\n"; sb << "// Normalize a vector\n"; -sb << "__generic __intrinsic_op vector normalize(vector x);\n"; +sb << "__generic vector normalize(vector x);\n"; sb << "\n"; sb << "// Raise to a power\n"; -sb << "__generic __intrinsic_op T pow(T x, T y);\n"; -sb << "__generic __intrinsic_op vector pow(vector x, vector y);\n"; -sb << "__generic __intrinsic_op matrix pow(matrix x, matrix y);\n"; +sb << "__generic T pow(T x, T y);\n"; +sb << "__generic vector pow(vector x, vector y);\n"; +sb << "__generic matrix pow(matrix x, matrix y);\n"; sb << "\n"; sb << "// Output message\n"; sb << "\n"; -sb << "// __intrinsic_op void printf( string format, ... );\n"; +sb << "// void printf( string format, ... );\n"; sb << "\n"; sb << "// Tessellation factor fixup routines\n"; sb << "\n"; -sb << "__intrinsic_op void Process2DQuadTessFactorsAvg(\n"; +sb << "void Process2DQuadTessFactorsAvg(\n"; sb << " in float4 RawEdgeFactors,\n"; sb << " in float2 InsideScale,\n"; sb << " out float4 RoundedEdgeTessFactors,\n"; sb << " out float2 RoundedInsideTessFactors,\n"; sb << " out float2 UnroundedInsideTessFactors);\n"; sb << "\n"; -sb << "__intrinsic_op void Process2DQuadTessFactorsMax(\n"; +sb << "void Process2DQuadTessFactorsMax(\n"; sb << " in float4 RawEdgeFactors,\n"; sb << " in float2 InsideScale,\n"; sb << " out float4 RoundedEdgeTessFactors,\n"; sb << " out float2 RoundedInsideTessFactors,\n"; sb << " out float2 UnroundedInsideTessFactors);\n"; sb << "\n"; -sb << "__intrinsic_op void Process2DQuadTessFactorsMin(\n"; +sb << "void Process2DQuadTessFactorsMin(\n"; sb << " in float4 RawEdgeFactors,\n"; sb << " in float2 InsideScale,\n"; sb << " out float4 RoundedEdgeTessFactors,\n"; sb << " out float2 RoundedInsideTessFactors,\n"; sb << " out float2 UnroundedInsideTessFactors);\n"; sb << "\n"; -sb << "__intrinsic_op void ProcessIsolineTessFactors(\n"; +sb << "void ProcessIsolineTessFactors(\n"; sb << " in float RawDetailFactor,\n"; sb << " in float RawDensityFactor,\n"; sb << " out float RoundedDetailFactor,\n"; sb << " out float RoundedDensityFactor);\n"; sb << "\n"; -sb << "__intrinsic_op void ProcessQuadTessFactorsAvg(\n"; +sb << "void ProcessQuadTessFactorsAvg(\n"; sb << " in float4 RawEdgeFactors,\n"; sb << " in float InsideScale,\n"; sb << " out float4 RoundedEdgeTessFactors,\n"; sb << " out float2 RoundedInsideTessFactors,\n"; sb << " out float2 UnroundedInsideTessFactors);\n"; sb << "\n"; -sb << "__intrinsic_op void ProcessQuadTessFactorsMax(\n"; +sb << "void ProcessQuadTessFactorsMax(\n"; sb << " in float4 RawEdgeFactors,\n"; sb << " in float InsideScale,\n"; sb << " out float4 RoundedEdgeTessFactors,\n"; sb << " out float2 RoundedInsideTessFactors,\n"; sb << " out float2 UnroundedInsideTessFactors);\n"; sb << "\n"; -sb << "__intrinsic_op void ProcessQuadTessFactorsMin(\n"; +sb << "void ProcessQuadTessFactorsMin(\n"; sb << " in float4 RawEdgeFactors,\n"; sb << " in float InsideScale,\n"; sb << " out float4 RoundedEdgeTessFactors,\n"; sb << " out float2 RoundedInsideTessFactors,\n"; sb << " out float2 UnroundedInsideTessFactors);\n"; sb << "\n"; -sb << "__intrinsic_op void ProcessTriTessFactorsAvg(\n"; +sb << "void ProcessTriTessFactorsAvg(\n"; sb << " in float3 RawEdgeFactors,\n"; sb << " in float InsideScale,\n"; sb << " out float3 RoundedEdgeTessFactors,\n"; sb << " out float RoundedInsideTessFactor,\n"; sb << " out float UnroundedInsideTessFactor);\n"; sb << "\n"; -sb << "__intrinsic_op void ProcessTriTessFactorsMax(\n"; +sb << "void ProcessTriTessFactorsMax(\n"; sb << " in float3 RawEdgeFactors,\n"; sb << " in float InsideScale,\n"; sb << " out float3 RoundedEdgeTessFactors,\n"; sb << " out float RoundedInsideTessFactor,\n"; sb << " out float UnroundedInsideTessFactor);\n"; sb << "\n"; -sb << "__intrinsic_op void ProcessTriTessFactorsMin(\n"; +sb << "void ProcessTriTessFactorsMin(\n"; sb << " in float3 RawEdgeFactors,\n"; sb << " in float InsideScale,\n"; sb << " out float3 RoundedEdgeTessFactors,\n"; @@ -798,38 +782,36 @@ sb << " out float RoundedInsideTessFactors,\n"; sb << " out float UnroundedInsideTessFactors);\n"; sb << "\n"; sb << "// Degrees to radians\n"; -sb << "__generic __intrinsic_op T radians(T x);\n"; -sb << "__generic __intrinsic_op vector radians(vector x);\n"; -sb << "__generic __intrinsic_op matrix radians(matrix x);\n"; +sb << "__generic T radians(T x);\n"; +sb << "__generic vector radians(vector x);\n"; +sb << "__generic matrix radians(matrix x);\n"; sb << "\n"; sb << "// Approximate reciprocal\n"; -sb << "__generic __intrinsic_op T rcp(T x);\n"; -sb << "__generic __intrinsic_op vector rcp(vector x);\n"; -sb << "__generic __intrinsic_op matrix rcp(matrix x);\n"; +sb << "__generic T rcp(T x);\n"; +sb << "__generic vector rcp(vector x);\n"; +sb << "__generic matrix rcp(matrix x);\n"; sb << "\n"; sb << "// Reflect incident vector across plane with given normal\n"; sb << "__generic\n"; -sb << "__intrinsic_op\n"; sb << "vector reflect(vector i, vector n);\n"; sb << "\n"; sb << "// Refract incident vector given surface normal and index of refraction\n"; sb << "__generic\n"; -sb << "__intrinsic_op\n"; sb << "vector refract(vector i, vector n, float eta);\n"; sb << "\n"; sb << "// Reverse order of bits\n"; -sb << "__intrinsic_op uint reversebits(uint value);\n"; +sb << "uint reversebits(uint value);\n"; sb << "__generic vector reversebits(vector value);\n"; sb << "\n"; sb << "// Round-to-nearest\n"; -sb << "__generic __intrinsic_op T round(T x);\n"; -sb << "__generic __intrinsic_op vector round(vector x);\n"; -sb << "__generic __intrinsic_op matrix round(matrix x);\n"; +sb << "__generic T round(T x);\n"; +sb << "__generic vector round(vector x);\n"; +sb << "__generic matrix round(matrix x);\n"; sb << "\n"; sb << "// Reciprocal of square root\n"; -sb << "__generic __intrinsic_op T rsqrt(T x);\n"; -sb << "__generic __intrinsic_op vector rsqrt(vector x);\n"; -sb << "__generic __intrinsic_op matrix rsqrt(matrix x);\n"; +sb << "__generic T rsqrt(T x);\n"; +sb << "__generic vector rsqrt(vector x);\n"; +sb << "__generic matrix rsqrt(matrix x);\n"; sb << "\n"; sb << "// Clamp value to [0,1] range\n"; sb << "__generic\n"; @@ -877,9 +859,9 @@ sb << "}\n"; sb << "\n"; sb << "\n"; sb << "// Extract sign of value\n"; -sb << "__generic __intrinsic_op int sign(T x);\n"; -sb << "__generic __intrinsic_op vector sign(vector x);\n"; -sb << "__generic __intrinsic_op matrix sign(matrix x);\n"; +sb << "__generic int sign(T x);\n"; +sb << "__generic vector sign(vector x);\n"; +sb << "__generic matrix sign(matrix x);\n"; sb << "\n"; sb << "\n"; sb << "// Sine\n"; @@ -888,127 +870,127 @@ sb << "__generic vector sin(ve sb << "__generic matrix sin(matrix x);\n"; sb << "\n"; sb << "// Sine and cosine\n"; -sb << "__generic __intrinsic_op void sincos(T x, out T s, out T c);\n"; -sb << "__generic __intrinsic_op void sincos(vector x, out vector s, out vector c);\n"; -sb << "__generic __intrinsic_op void sincos(matrix x, out matrix s, out matrix c);\n"; +sb << "__generic void sincos(T x, out T s, out T c);\n"; +sb << "__generic void sincos(vector x, out vector s, out vector c);\n"; +sb << "__generic void sincos(matrix x, out matrix s, out matrix c);\n"; sb << "\n"; sb << "// Hyperbolic Sine\n"; -sb << "__generic __intrinsic_op T sinh(T x);\n"; -sb << "__generic __intrinsic_op vector sinh(vector x);\n"; -sb << "__generic __intrinsic_op matrix sinh(matrix x);\n"; +sb << "__generic T sinh(T x);\n"; +sb << "__generic vector sinh(vector x);\n"; +sb << "__generic matrix sinh(matrix x);\n"; sb << "\n"; sb << "// Smooth step (Hermite interpolation)\n"; -sb << "__generic __intrinsic_op T smoothstep(T min, T max, T x);\n"; -sb << "__generic __intrinsic_op vector smoothstep(vector min, vector max, vector x);\n"; -sb << "__generic __intrinsic_op matrix smoothstep(matrix min, matrix max, matrix x);\n"; +sb << "__generic T smoothstep(T min, T max, T x);\n"; +sb << "__generic vector smoothstep(vector min, vector max, vector x);\n"; +sb << "__generic matrix smoothstep(matrix min, matrix max, matrix x);\n"; sb << "\n"; sb << "// Square root\n"; -sb << "__generic __intrinsic_op T sqrt(T x);\n"; -sb << "__generic __intrinsic_op vector sqrt(vector x);\n"; -sb << "__generic __intrinsic_op matrix sqrt(matrix x);\n"; +sb << "__generic T sqrt(T x);\n"; +sb << "__generic vector sqrt(vector x);\n"; +sb << "__generic matrix sqrt(matrix x);\n"; sb << "\n"; sb << "// Step function\n"; -sb << "__generic __intrinsic_op T step(T y, T x);\n"; -sb << "__generic __intrinsic_op vector step(vector y, vector x);\n"; -sb << "__generic __intrinsic_op matrix step(matrix y, matrix x);\n"; +sb << "__generic T step(T y, T x);\n"; +sb << "__generic vector step(vector y, vector x);\n"; +sb << "__generic matrix step(matrix y, matrix x);\n"; sb << "\n"; sb << "// Tangent\n"; -sb << "__generic __intrinsic_op T tan(T x);\n"; -sb << "__generic __intrinsic_op vector tan(vector x);\n"; -sb << "__generic __intrinsic_op matrix tan(matrix x);\n"; +sb << "__generic T tan(T x);\n"; +sb << "__generic vector tan(vector x);\n"; +sb << "__generic matrix tan(matrix x);\n"; sb << "\n"; sb << "// Hyperbolic tangent\n"; -sb << "__generic __intrinsic_op T tanh(T x);\n"; -sb << "__generic __intrinsic_op vector tanh(vector x);\n"; -sb << "__generic __intrinsic_op matrix tanh(matrix x);\n"; +sb << "__generic T tanh(T x);\n"; +sb << "__generic vector tanh(vector x);\n"; +sb << "__generic matrix tanh(matrix x);\n"; sb << "\n"; sb << "// Legacy texture-fetch operations\n"; sb << "\n"; sb << "/*\n"; -sb << "__intrinsic_op float4 tex1D(sampler1D s, float t);\n"; -sb << "__intrinsic_op float4 tex1D(sampler1D s, float t, float ddx, float ddy);\n"; -sb << "__intrinsic_op float4 tex1Dbias(sampler1D s, float4 t);\n"; -sb << "__intrinsic_op float4 tex1Dgrad(sampler1D s, float t, float ddx, float ddy);\n"; -sb << "__intrinsic_op float4 tex1Dlod(sampler1D s, float4 t);\n"; -sb << "__intrinsic_op float4 tex1Dproj(sampler1D s, float4 t);\n"; -sb << "\n"; -sb << "__intrinsic_op float4 tex2D(sampler2D s, float2 t);\n"; -sb << "__intrinsic_op float4 tex2D(sampler2D s, float2 t, float2 ddx, float2 ddy);\n"; -sb << "__intrinsic_op float4 tex2Dbias(sampler2D s, float4 t);\n"; -sb << "__intrinsic_op float4 tex2Dgrad(sampler2D s, float2 t, float2 ddx, float2 ddy);\n"; -sb << "__intrinsic_op float4 tex2Dlod(sampler2D s, float4 t);\n"; -sb << "__intrinsic_op float4 tex2Dproj(sampler2D s, float4 t);\n"; -sb << "\n"; -sb << "__intrinsic_op float4 tex3D(sampler3D s, float3 t);\n"; -sb << "__intrinsic_op float4 tex3D(sampler3D s, float3 t, float3 ddx, float3 ddy);\n"; -sb << "__intrinsic_op float4 tex3Dbias(sampler3D s, float4 t);\n"; -sb << "__intrinsic_op float4 tex3Dgrad(sampler3D s, float3 t, float3 ddx, float3 ddy);\n"; -sb << "__intrinsic_op float4 tex3Dlod(sampler3D s, float4 t);\n"; -sb << "__intrinsic_op float4 tex3Dproj(sampler3D s, float4 t);\n"; -sb << "\n"; -sb << "__intrinsic_op float4 texCUBE(samplerCUBE s, float3 t);\n"; -sb << "__intrinsic_op float4 texCUBE(samplerCUBE s, float3 t, float3 ddx, float3 ddy);\n"; -sb << "__intrinsic_op float4 texCUBEbias(samplerCUBE s, float4 t);\n"; -sb << "__intrinsic_op float4 texCUBEgrad(samplerCUBE s, float3 t, float3 ddx, float3 ddy);\n"; -sb << "__intrinsic_op float4 texCUBElod(samplerCUBE s, float4 t);\n"; -sb << "__intrinsic_op float4 texCUBEproj(samplerCUBE s, float4 t);\n"; +sb << "float4 tex1D(sampler1D s, float t);\n"; +sb << "float4 tex1D(sampler1D s, float t, float ddx, float ddy);\n"; +sb << "float4 tex1Dbias(sampler1D s, float4 t);\n"; +sb << "float4 tex1Dgrad(sampler1D s, float t, float ddx, float ddy);\n"; +sb << "float4 tex1Dlod(sampler1D s, float4 t);\n"; +sb << "float4 tex1Dproj(sampler1D s, float4 t);\n"; +sb << "\n"; +sb << "float4 tex2D(sampler2D s, float2 t);\n"; +sb << "float4 tex2D(sampler2D s, float2 t, float2 ddx, float2 ddy);\n"; +sb << "float4 tex2Dbias(sampler2D s, float4 t);\n"; +sb << "float4 tex2Dgrad(sampler2D s, float2 t, float2 ddx, float2 ddy);\n"; +sb << "float4 tex2Dlod(sampler2D s, float4 t);\n"; +sb << "float4 tex2Dproj(sampler2D s, float4 t);\n"; +sb << "\n"; +sb << "float4 tex3D(sampler3D s, float3 t);\n"; +sb << "float4 tex3D(sampler3D s, float3 t, float3 ddx, float3 ddy);\n"; +sb << "float4 tex3Dbias(sampler3D s, float4 t);\n"; +sb << "float4 tex3Dgrad(sampler3D s, float3 t, float3 ddx, float3 ddy);\n"; +sb << "float4 tex3Dlod(sampler3D s, float4 t);\n"; +sb << "float4 tex3Dproj(sampler3D s, float4 t);\n"; +sb << "\n"; +sb << "float4 texCUBE(samplerCUBE s, float3 t);\n"; +sb << "float4 texCUBE(samplerCUBE s, float3 t, float3 ddx, float3 ddy);\n"; +sb << "float4 texCUBEbias(samplerCUBE s, float4 t);\n"; +sb << "float4 texCUBEgrad(samplerCUBE s, float3 t, float3 ddx, float3 ddy);\n"; +sb << "float4 texCUBElod(samplerCUBE s, float4 t);\n"; +sb << "float4 texCUBEproj(samplerCUBE s, float4 t);\n"; sb << "*/\n"; sb << "\n"; sb << "// Matrix transpose\n"; -sb << "__generic __intrinsic_op matrix transpose(matrix x);\n"; +sb << "__generic matrix transpose(matrix x);\n"; sb << "\n"; sb << "// Truncate to integer\n"; -sb << "__generic __intrinsic_op T trunc(T x);\n"; -sb << "__generic __intrinsic_op vector trunc(vector x);\n"; -sb << "__generic __intrinsic_op matrix trunc(matrix x);\n"; +sb << "__generic T trunc(T x);\n"; +sb << "__generic vector trunc(vector x);\n"; +sb << "__generic matrix trunc(matrix x);\n"; sb << "\n"; sb << "// Shader model 6.0 stuff\n"; sb << "\n"; -sb << "__intrinsic_op uint GlobalOrderedCountIncrement(uint countToAppendForThisLane);\n"; +sb << "uint GlobalOrderedCountIncrement(uint countToAppendForThisLane);\n"; sb << "\n"; -sb << "__generic __intrinsic_op T QuadReadLaneAt(T sourceValue, int quadLaneID);\n"; -sb << "__generic __intrinsic_op vector QuadReadLaneAt(vector sourceValue, int quadLaneID);\n"; -sb << "__generic __intrinsic_op matrix QuadReadLaneAt(matrix sourceValue, int quadLaneID);\n"; +sb << "__generic T QuadReadLaneAt(T sourceValue, int quadLaneID);\n"; +sb << "__generic vector QuadReadLaneAt(vector sourceValue, int quadLaneID);\n"; +sb << "__generic matrix QuadReadLaneAt(matrix sourceValue, int quadLaneID);\n"; sb << "\n"; -sb << "__generic __intrinsic_op T QuadSwapX(T localValue);\n"; -sb << "__generic __intrinsic_op vector QuadSwapX(vector localValue);\n"; -sb << "__generic __intrinsic_op matrix QuadSwapX(matrix localValue);\n"; +sb << "__generic T QuadSwapX(T localValue);\n"; +sb << "__generic vector QuadSwapX(vector localValue);\n"; +sb << "__generic matrix QuadSwapX(matrix localValue);\n"; sb << "\n"; -sb << "__generic __intrinsic_op T QuadSwapY(T localValue);\n"; -sb << "__generic __intrinsic_op vector QuadSwapY(vector localValue);\n"; -sb << "__generic __intrinsic_op matrix QuadSwapY(matrix localValue);\n"; +sb << "__generic T QuadSwapY(T localValue);\n"; +sb << "__generic vector QuadSwapY(vector localValue);\n"; +sb << "__generic matrix QuadSwapY(matrix localValue);\n"; sb << "\n"; -sb << "__generic __intrinsic_op T WaveAllBitAnd(T expr);\n"; -sb << "__generic __intrinsic_op vector WaveAllBitAnd(vector expr);\n"; -sb << "__generic __intrinsic_op matrix WaveAllBitAnd(matrix expr);\n"; +sb << "__generic T WaveAllBitAnd(T expr);\n"; +sb << "__generic vector WaveAllBitAnd(vector expr);\n"; +sb << "__generic matrix WaveAllBitAnd(matrix expr);\n"; sb << "\n"; -sb << "__generic __intrinsic_op T WaveAllBitOr(T expr);\n"; -sb << "__generic __intrinsic_op vector WaveAllBitOr(vector expr);\n"; -sb << "__generic __intrinsic_op matrix WaveAllBitOr(matrix expr);\n"; +sb << "__generic T WaveAllBitOr(T expr);\n"; +sb << "__generic vector WaveAllBitOr(vector expr);\n"; +sb << "__generic matrix WaveAllBitOr(matrix expr);\n"; sb << "\n"; -sb << "__generic __intrinsic_op T WaveAllBitXor(T expr);\n"; -sb << "__generic __intrinsic_op vector WaveAllBitXor(vector expr);\n"; -sb << "__generic __intrinsic_op matrix WaveAllBitXor(matrix expr);\n"; +sb << "__generic T WaveAllBitXor(T expr);\n"; +sb << "__generic vector WaveAllBitXor(vector expr);\n"; +sb << "__generic matrix WaveAllBitXor(matrix expr);\n"; sb << "\n"; -sb << "__generic __intrinsic_op T WaveAllMax(T expr);\n"; -sb << "__generic __intrinsic_op vector WaveAllMax(vector expr);\n"; -sb << "__generic __intrinsic_op matrix WaveAllMax(matrix expr);\n"; +sb << "__generic T WaveAllMax(T expr);\n"; +sb << "__generic vector WaveAllMax(vector expr);\n"; +sb << "__generic matrix WaveAllMax(matrix expr);\n"; sb << "\n"; -sb << "__generic __intrinsic_op T WaveAllMin(T expr);\n"; -sb << "__generic __intrinsic_op vector WaveAllMin(vector expr);\n"; -sb << "__generic __intrinsic_op matrix WaveAllMin(matrix expr);\n"; +sb << "__generic T WaveAllMin(T expr);\n"; +sb << "__generic vector WaveAllMin(vector expr);\n"; +sb << "__generic matrix WaveAllMin(matrix expr);\n"; sb << "\n"; -sb << "__generic __intrinsic_op T WaveAllProduct(T expr);\n"; -sb << "__generic __intrinsic_op vector WaveAllProduct(vector expr);\n"; -sb << "__generic __intrinsic_op matrix WaveAllProduct(matrix expr);\n"; +sb << "__generic T WaveAllProduct(T expr);\n"; +sb << "__generic vector WaveAllProduct(vector expr);\n"; +sb << "__generic matrix WaveAllProduct(matrix expr);\n"; sb << "\n"; -sb << "__generic __intrinsic_op T WaveAllSum(T expr);\n"; -sb << "__generic __intrinsic_op vector WaveAllSum(vector expr);\n"; -sb << "__generic __intrinsic_op matrix WaveAllSum(matrix expr);\n"; +sb << "__generic T WaveAllSum(T expr);\n"; +sb << "__generic vector WaveAllSum(vector expr);\n"; +sb << "__generic matrix WaveAllSum(matrix expr);\n"; sb << "\n"; -sb << "__intrinsic_op bool WaveAllEqual(bool expr);\n"; -sb << "__intrinsic_op bool WaveAllTrue(bool expr);\n"; -sb << "__intrinsic_op bool WaveAnyTrue(bool expr);\n"; +sb << "bool WaveAllEqual(bool expr);\n"; +sb << "bool WaveAllTrue(bool expr);\n"; +sb << "bool WaveAnyTrue(bool expr);\n"; sb << "\n"; sb << "uint64_t WaveBallot(bool expr);\n"; sb << "\n"; @@ -1020,21 +1002,21 @@ sb << "bool WaveIsHelperLane();\n"; sb << "\n"; sb << "bool WaveOnce();\n"; sb << "\n"; -sb << "__generic __intrinsic_op T WavePrefixProduct(T expr);\n"; -sb << "__generic __intrinsic_op vector WavePrefixProduct(vector expr);\n"; -sb << "__generic __intrinsic_op matrix WavePrefixProduct(matrix expr);\n"; +sb << "__generic T WavePrefixProduct(T expr);\n"; +sb << "__generic vector WavePrefixProduct(vector expr);\n"; +sb << "__generic matrix WavePrefixProduct(matrix expr);\n"; sb << "\n"; -sb << "__generic __intrinsic_op T WavePrefixSum(T expr);\n"; -sb << "__generic __intrinsic_op vector WavePrefixSum(vector expr);\n"; -sb << "__generic __intrinsic_op matrix WavePrefixSum(matrix expr);\n"; +sb << "__generic T WavePrefixSum(T expr);\n"; +sb << "__generic vector WavePrefixSum(vector expr);\n"; +sb << "__generic matrix WavePrefixSum(matrix expr);\n"; sb << "\n"; -sb << "__generic __intrinsic_op T WaveReadFirstLane(T expr);\n"; -sb << "__generic __intrinsic_op vector WaveReadFirstLane(vector expr);\n"; -sb << "__generic __intrinsic_op matrix WaveReadFirstLane(matrix expr);\n"; +sb << "__generic T WaveReadFirstLane(T expr);\n"; +sb << "__generic vector WaveReadFirstLane(vector expr);\n"; +sb << "__generic matrix WaveReadFirstLane(matrix expr);\n"; sb << "\n"; -sb << "__generic __intrinsic_op T WaveReadLaneAt(T expr, int laneIndex);\n"; -sb << "__generic __intrinsic_op vector WaveReadLaneAt(vector expr, int laneIndex);\n"; -sb << "__generic __intrinsic_op matrix WaveReadLaneAt(matrix expr, int laneIndex);\n"; +sb << "__generic T WaveReadLaneAt(T expr, int laneIndex);\n"; +sb << "__generic vector WaveReadLaneAt(vector expr, int laneIndex);\n"; +sb << "__generic matrix WaveReadLaneAt(matrix expr, int laneIndex);\n"; sb << "\n"; sb << "// `typedef`s to help with the fact that HLSL has been sorta-kinda case insensitive at various points\n"; sb << "typedef Texture2D texture2D;\n"; @@ -1095,15 +1077,15 @@ for (int aa = 0; aa < kBaseBufferAccessLevelCount; ++aa) sb << kBaseBufferAccessLevels[aa].name; sb << "Buffer {\n"; - sb << "__intrinsic_op void GetDimensions(out uint dim);\n"; + sb << "void GetDimensions(out uint dim);\n"; sb << "__target_intrinsic(glsl, \"texelFetch($P, $0)$z\")\n"; - sb << "__intrinsic_op T Load(int location);\n"; + sb << "T Load(int location);\n"; - sb << "__intrinsic_op T Load(int location, out uint status);\n"; + sb << "T Load(int location, out uint status);\n"; sb << "__target_intrinsic(glsl, \"texelFetch($P, int($0))$z\")\n"; - sb << "__intrinsic_op __subscript(uint index) -> T"; + sb << "__subscript(uint index) -> T"; if (kBaseBufferAccessLevels[aa].access != SLANG_RESOURCE_ACCESS_READ) { -- cgit v1.2.3 From 9640df03814593d2f4b34c36bbec6756b1ed7fba Mon Sep 17 00:00:00 2001 From: Tim Foley Date: Tue, 7 Nov 2017 08:31:06 -0800 Subject: Handle "ThisType" subsitutions when specialization generics in the IR The original code is handling the issue where a call site might be specializing a generic function, so it has a `DeclRef` that represents what it wants to specialize, but the callee is actually a different overload of the same generic function (e.g., a target-specific overload) and so we need to construct a set of substitutions that are equivalent (same arguments), but point to different `GenericDecl`s. That code was making some bad assumptions, though: 1. It assumed that the substitutions list would always start with a generic substitution (no longer true with `ThisTypeSubstitution`. 2. It assumed that only the top-most substitution would need to be translated. This assumption is probably safe for now, but it could break down if we ever introduced an ability for a type to be re-opened to introduce new (target-specific) overloads of its members. The new approach goes ahead and does a deep copy of the substitition list (but a shallow copy of the arguments), and only copies the generic substititions for now. --- source/slang/ir.cpp | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 76 insertions(+), 4 deletions(-) (limited to 'source') diff --git a/source/slang/ir.cpp b/source/slang/ir.cpp index d6a01a484..439bc7797 100644 --- a/source/slang/ir.cpp +++ b/source/slang/ir.cpp @@ -3866,6 +3866,78 @@ namespace Slang return originalType->Substitute(subst).As(); } + // Given a list of substitutions, return the inner-most + // generic substitution in the list, or NULL if there + // are no generic substitutions. + RefPtr getInnermostGenericSubst( + Substitutions* inSubst) + { + auto subst = inSubst; + while( subst ) + { + GenericSubstitution* genericSubst = dynamic_cast(subst); + if(genericSubst) + return genericSubst; + + subst = subst->outer; + } + return nullptr; + } + + RefPtr getInnermostGenericDecl( + Decl* inDecl) + { + auto decl = inDecl; + while( decl ) + { + GenericDecl* genericDecl = dynamic_cast(decl); + if(genericDecl) + return genericDecl; + + decl = decl->ParentDecl; + } + return nullptr; + } + + // This function takes a list of substitutions that we'd + // like to apply, but which (1) might apply to a different + // declaration in cases where we have got target-specific + // overloads in the mix, and (2) might include some `ThisType` + // substitutions, which we don't care about in this context, + // and produces a new set of substitutiosn without these + // two issues. + RefPtr cloneSubstitutionsForSpecialization( + IRSharedGenericSpecContext* sharedContext, + Substitutions* oldSubst, + Decl* newDecl) + { + // We will "peel back" layers of substitutions until + // we find our first generic subsitution. + auto oldGenericSubst = getInnermostGenericSubst(oldSubst); + if(!oldGenericSubst) + return nullptr; + + // We will also peel back layers of declarations until + // we find our first generic decl. + auto newGenericDecl = getInnermostGenericDecl(newDecl); + if( !newGenericDecl ) + { +// SLANG_UNEXPECTED("generic subst without generic decl"); + return nullptr; + } + + RefPtr newSubst = new GenericSubstitution(); + newSubst->genericDecl = newGenericDecl; + newSubst->args = oldGenericSubst->args; + + newSubst->outer = cloneSubstitutionsForSpecialization( + sharedContext, + oldGenericSubst->outer, + newGenericDecl->ParentDecl); + + return newSubst; + } + IRFunc* getSpecializedFunc( IRSharedGenericSpecContext* sharedContext, @@ -3897,10 +3969,10 @@ namespace Slang // using a different overload of a target-specific function, // so we need to create a dummy substitution here, to make // sure it used the correct generic. - RefPtr newSubst = new GenericSubstitution(); - newSubst->genericDecl = genericFunc->genericDecl; - auto specDeclRefSubst = specDeclRef.substitutions.As(); - newSubst->args = specDeclRefSubst->args; + RefPtr newSubst = cloneSubstitutionsForSpecialization( + sharedContext, + specDeclRef.substitutions, + genericFunc->genericDecl); IRGenericSpecContext context; context.shared = sharedContext; -- cgit v1.2.3 From 93a444fe1b5f1e3c6da67db4d948df53a0bdb3f6 Mon Sep 17 00:00:00 2001 From: Tim Foley Date: Tue, 7 Nov 2017 09:38:32 -0800 Subject: Attach correct types to subscript accessors Subscript declarations can have nested "accessor" declarations for the get/set behavior: ``` __subscript(int index) -> float { get { ... } set { ... } } ``` The AST type checks an expression like `a[i]` into a call to an appropriate `__subscript` declaration, and reads the return type off of that, but doesn't drill down to the individual getters/setters. During IR code generation, we need to resolve a call to the subscript operation down to the actual getter or setter, since those are what will have the executable code (or be intrinsics). If we have a non-intrinsic accessor, then we end up asking for its "return type" and get NULL, which crashes the compiler. The fix in this case is to add a bit more semantic checking for accessors, mostly just so that we can have them copy the return type from their parent declaration. While we are at it, this change goes ahead and has an accessor validate that the parent declaration is one that should be allowed, and emit a diagnostic if it is nested in an improper place. --- source/slang/check.cpp | 22 ++++++++++++++++++++++ source/slang/diagnostic-defs.h | 1 + 2 files changed, 23 insertions(+) (limited to 'source') diff --git a/source/slang/check.cpp b/source/slang/check.cpp index ed2ed4a1b..6bb7c232f 100644 --- a/source/slang/check.cpp +++ b/source/slang/check.cpp @@ -3471,11 +3471,33 @@ namespace Slang decl->SetCheckState(DeclCheckState::CheckedHeader); + for(auto mm : decl->Members) + { + checkDecl(mm); + } + decl->SetCheckState(DeclCheckState::Checked); } void visitAccessorDecl(AccessorDecl* decl) { + // An acessor must appear nested inside a subscript declaration (today), + // or a property declaration (when we add them). It will derive + // its return type from the outer declaration, so we handle both + // of these checks at the same place. + auto parent = decl->ParentDecl; + if(auto parentSubscript = dynamic_cast(parent)) + { + decl->ReturnType = parentSubscript->ReturnType; + } + // TODO: when we add "property" declarations, check for them here + else + { + getSink()->diagnose(decl, Diagnostics::accessorMustBeInsideSubscriptOrProperty); + } + + decl->SetCheckState(DeclCheckState::CheckedHeader); + // TODO: check the body! decl->SetCheckState(DeclCheckState::Checked); diff --git a/source/slang/diagnostic-defs.h b/source/slang/diagnostic-defs.h index 52f5d48a0..10b2dbd1e 100644 --- a/source/slang/diagnostic-defs.h +++ b/source/slang/diagnostic-defs.h @@ -246,6 +246,7 @@ DIAGNOSTIC(38003, Error, entryPointSymbolNotAFunction, "entry point '$0' must be DIAGNOSTIC(38100, Error, typeDoesntImplementInterfaceRequirement, "type '$0' does not provide required interface member '$1'") DIAGNOSTIC(38101, Error, thisExpressionOutsideOfTypeDecl, "'this' expression can only be used in members of an aggregate type") DIAGNOSTIC(38102, Error, initializerNotInsideType, "an 'init' declaration is only allowed inside a type or 'extension' declaration") +DIAGNOSTIC(38102, Error, accessorMustBeInsideSubscriptOrProperty, "an accessor declaration is only allowed inside a subscript or property declaration") // // 4xxxx - IL code generation. -- cgit v1.2.3 From 5c220292d6ac2674942bb5f1bb09fe1817151c11 Mon Sep 17 00:00:00 2001 From: Tim Foley Date: Tue, 7 Nov 2017 09:25:41 -0800 Subject: Fixes for name mangling/demangling The source of a lot of these changes is that our current strategy for dealing with "builtin" operations when emitting HLSL from the IR is to de-mangle the mangled name of an operation, and then emit HLSL code for a function call to an operation with that de-mangled name. This change introduces a few fixups for that work: - It adds support for parsing the mangled names of generics (specialized and unspecialized) - It adds logic for detecting when the operation being invoked is a member function - This is currently a bit ugly, since we compare the number of actual arguments we have in the IR against the number of parameters declared for the callee, and if they don't match we assume we have an extra `this` argument. On the mangling side, we add (hacky) support for mangling a function name when its types involve generic parameters, e.g.: ``` __generic T length(vector v); ``` In this case the mangled name of the function needs to include a mangling for the type `vector` which means it also needs to include a mangling for `N`. The reason I describe this support as "hacky" is because we really shouldn't be reproducing the names `T` or `N` in the mangled symbol name. By doing so we make it so that a user changing the name of a generic parameter would break (IR) binary compatibility with existing code that was separately compiled. I've included comments in the code about a better way to handle this, but it isn't a priorit right now since binary compatibility isn't something meaningful until we start emitting usable bytecode modules. --- source/slang/emit.cpp | 144 +++++++++++++++++++++++++++++++++++++++++++++--- source/slang/mangle.cpp | 12 ++++ 2 files changed, 147 insertions(+), 9 deletions(-) (limited to 'source') diff --git a/source/slang/emit.cpp b/source/slang/emit.cpp index d95946204..7e4fca4e5 100644 --- a/source/slang/emit.cpp +++ b/source/slang/emit.cpp @@ -4677,7 +4677,7 @@ emitDeclImpl(decl, nullptr); if(c == '0') return 0; - int count = 0; + UInt count = 0; for(;;) { count = count*10 + c - '0'; @@ -4689,18 +4689,117 @@ emitDeclImpl(decl, nullptr); } } + void readGenericParam() + { + switch(peek()) + { + case 'T': + get(); + break; + + default: + SLANG_UNEXPECTED("bad name mangling"); + break; + } + } + + void readGenericParams() + { + expect("g"); + UInt paramCount = readCount(); + for(UInt pp = 0; pp < paramCount; pp++) + { + readGenericParam(); + } + } + + void readSimpleIntVal() + { + int c = peek(); + if(isDigit(c)) + { + get(); + } + else + { + readVal(); + } + } + + void readType() + { + int c = peek(); + switch(c) + { + case 'V': + case 'b': + case 'i': + case 'u': + case 'U': + case 'h': + case 'f': + case 'd': + get(); + break; + + case 'v': + get(); + readSimpleIntVal(); + readType(); + break; + + default: + // TODO: need to read a named type + // here... + break; + } + } + + void readVal() + { + // TODO: handle other cases here + readType(); + } + + void readGenericArg() + { + readVal(); + } + + void readGenericArgs() + { + expect("G"); + UInt argCount = readCount(); + for(UInt aa = 0; aa < argCount; aa++) + { + readGenericArg(); + } + } + UnownedStringSlice readSimpleName() { UnownedStringSlice result; for(;;) { int c = peek(); + + if(c == 'g') + { + readGenericParams(); + continue; + } + else if(c == 'G') + { + readGenericArgs(); + continue; + } + if(!isDigit((char)c)) return result; // Read the length part - int count = readCount(); - if(count > (end_ - cursor_)) + UInt count = readCount(); + if(count > UInt(end_ - cursor_)) { SLANG_UNEXPECTED("bad name mangling"); UNREACHABLE_RETURN(result); @@ -4710,6 +4809,12 @@ emitDeclImpl(decl, nullptr); cursor_ += count; } } + + UInt readParamCount() + { + expect("p"); + return readCount(); + } }; void emitIntrinsicCallExpr( @@ -4726,16 +4831,37 @@ emitDeclImpl(decl, nullptr); auto name = um.readSimpleName(); - // TODO: need to detect if name represents - // a member function, etc. + // The mangled function name currently records + // the number of explicit parameters, and thus + // doesn't include the implicit `this` parameter. + // We can compare the argument and parameter counts + // to figure out whether we have a member function call. + UInt paramCount = um.readParamCount(); + + // For a call with N arguments, the instruction will + // have N+1 operands. + UInt operandCount = inst->getArgCount(); + UInt argCount = operandCount - 1; + UInt operandIndex = 1; + + if(argCount != paramCount) + { + // Looks like a member function call + emit("("); + emitIROperand(ctx, inst->getArg(operandIndex)); + emit(")."); + + operandIndex++; + } emit(name); emit("("); - UInt argCount = inst->getArgCount(); - for( UInt aa = 1; aa < argCount; ++aa ) + bool first = true; + for(; operandIndex < operandCount; ++operandIndex ) { - if(aa != 1) emit(", "); - emitIROperand(ctx, inst->getArg(aa)); + if(!first) emit(", "); + emitIROperand(ctx, inst->getArg(operandIndex)); + first = false; } emit(")"); } diff --git a/source/slang/mangle.cpp b/source/slang/mangle.cpp index b9fba6380..dca48f671 100644 --- a/source/slang/mangle.cpp +++ b/source/slang/mangle.cpp @@ -152,6 +152,18 @@ namespace Slang // value, so we certainly don't want to include // it in the mangling. } + else if( auto genericParamIntVal = dynamic_cast(val) ) + { + // TODO: we shouldn't be including the names of generic parameters + // anywhere in mangled names, since changing parameter names + // shouldn't break binary compatibility. + // + // The right solution in the long term is for generic parameters + // (both types and values) to be mangled in terms of their + // "depth" (how many outer generics) and "index" (which + // parameter are they at the specified depth). + emitName(context, genericParamIntVal->declRef.GetName()); + } else { SLANG_UNEXPECTED("unimplemented case in mangling"); -- cgit v1.2.3 From 722105feb1f11ea727af52bc5a484ddf4320e74d Mon Sep 17 00:00:00 2001 From: Tim Foley Date: Tue, 7 Nov 2017 09:45:08 -0800 Subject: Add a comparison operator to UnownedStringSlice This is to allow me to compare for particular names in my de-mangling logic in `emit.cpp`. --- source/core/slang-string.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'source') diff --git a/source/core/slang-string.h b/source/core/slang-string.h index 0808d9715..a0f2b48a1 100644 --- a/source/core/slang-string.h +++ b/source/core/slang-string.h @@ -154,6 +154,22 @@ namespace Slang return endData; } + UInt size() const + { + return endData - beginData; + } + + bool operator==(UnownedStringSlice const& other) + { + return size() == other.size() + && memcmp(begin(), other.begin(), size()) == 0; + } + + bool operator==(char const* str) + { + return (*this) == UnownedStringSlice(str, str + strlen(str)); + } + private: char const* beginData; char const* endData; -- cgit v1.2.3 From 97a1a95b6192599e038a26704756a914368f3d3a Mon Sep 17 00:00:00 2001 From: Tim Foley Date: Tue, 7 Nov 2017 09:55:53 -0800 Subject: Try to fix up IR emit for subscript calls This code isn't especially useful right now since most of the important subscripts are still special-cased with `__intrinsic_op`, but the idea is that if we de-mangle an intrinsic operation's name and see it is called `operator[]` then we are probably calling a subscript, and should emit an appropriate expression. Aside: this change has pointed out to me that our current name mangling isn't properly handling non-alphanumeric characters, so we'll be in trouble as soon as we have non-intrinsic subscripts, operators, etc. --- source/slang/emit.cpp | 49 +++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 39 insertions(+), 10 deletions(-) (limited to 'source') diff --git a/source/slang/emit.cpp b/source/slang/emit.cpp index 7e4fca4e5..615fb47a0 100644 --- a/source/slang/emit.cpp +++ b/source/slang/emit.cpp @@ -4664,7 +4664,7 @@ emitDeclImpl(decl, nullptr); expect("_S"); } - int readCount() + UInt readCount() { int c = peek(); if(!isDigit((char)c)) @@ -4822,15 +4822,50 @@ emitDeclImpl(decl, nullptr); IRCall* inst, IRFunc* func) { - // TODO: we need to inspect the mangled name, - // and construct a suitable expression from it... + // For a call with N arguments, the instruction will + // have N+1 operands. We will start consuming operands + // starting at the index 1. + UInt operandCount = inst->getArgCount(); + UInt argCount = operandCount - 1; + UInt operandIndex = 1; - UnmangleContext um(func->mangledName); + // Our current strategy for dealing with intrinsic + // calls is to "un-mangle" the mangled name, in + // order to figure out what the user was originally + // calling. This is a bit messy, and there might + // be better strategies (including just stuffing + // a pointer to the original decl onto the callee). + UnmangleContext um(func->mangledName); um.startUnmangling(); + // We'll read through the qualified name of the + // symbol (e.g., `Texture2D.Sample`) and then + // only keep the last segment of the name (e.g., + // the `Sample` part). auto name = um.readSimpleName(); + // We will special-case some names here, that + // represent callable declarations that aren't + // ordinary functions, and thus may use different + // syntax. + if(name == "operator[]") + { + // The user is invoking a built-in subscript operator + emit("("); + emitIROperand(ctx, inst->getArg(operandIndex++)); + emit(")["); + emitIROperand(ctx, inst->getArg(operandIndex++)); + emit("]"); + + if(operandIndex < operandCount) + { + emit(" = "); + emitIROperand(ctx, inst->getArg(operandIndex++)); + } + return; + } + // The mangled function name currently records // the number of explicit parameters, and thus // doesn't include the implicit `this` parameter. @@ -4838,12 +4873,6 @@ emitDeclImpl(decl, nullptr); // to figure out whether we have a member function call. UInt paramCount = um.readParamCount(); - // For a call with N arguments, the instruction will - // have N+1 operands. - UInt operandCount = inst->getArgCount(); - UInt argCount = operandCount - 1; - UInt operandIndex = 1; - if(argCount != paramCount) { // Looks like a member function call -- cgit v1.2.3 From f4c4f63c0cfad93b1eacf9300eb8e06d2c78ccc9 Mon Sep 17 00:00:00 2001 From: Tim Foley Date: Tue, 7 Nov 2017 10:02:10 -0800 Subject: Fix for emitting subscript calls in HLSL/GLSL The old approach was relying on an `__intrinsic_op` modifier to tell us we need to do something special with an `InvokeExpr`, but a previous change removed a bunch of those modifiers. Instead, we will now check for calls to subscript declarations as part of the normal flow of emitting *any* call, similar to what is done for constructor calls already. Eventually we should be able to eliminate the special case in the `__intrinsic_op` path, but I'm holding off on that because the AST emit logic can probably be cleaned up a *lot* once it doesn't have to be used for cross-compilation as well. --- source/slang/emit.cpp | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) (limited to 'source') diff --git a/source/slang/emit.cpp b/source/slang/emit.cpp index 615fb47a0..c67bb7b29 100644 --- a/source/slang/emit.cpp +++ b/source/slang/emit.cpp @@ -1614,6 +1614,32 @@ struct EmitVisitor } } + void emitSimpleSubscriptCallExpr( + RefPtr callExpr, + EOpInfo /*outerPrec*/) + { + auto funcExpr = callExpr->FunctionExpr; + + // We expect any subscript operation to be invoked as a member, + // so the function expression had better be in the correct form. + auto memberExpr = funcExpr.As(); + if(!memberExpr) + { + SLANG_UNEXPECTED("subscript needs base expression"); + } + + Emit("("); + EmitExpr(memberExpr->BaseExpression); + Emit(")["); + UInt argCount = callExpr->Arguments.Count(); + for (UInt aa = 0; aa < argCount; ++aa) + { + if (aa != 0) Emit(", "); + EmitExpr(callExpr->Arguments[aa]); + } + Emit("]"); + } + // Emit a call expression that doesn't involve any special cases, // just an expression of the form `f(a0, a1, ...)` void emitSimpleCallExpr( @@ -1632,6 +1658,18 @@ struct EmitVisitor emitSimpleConstructorCallExpr(callExpr, outerPrec); return; } + + if(auto acessorDeclRef = declRef.As()) + { + declRef = acessorDeclRef.GetParent(); + } + + if(auto subscriptDeclRef = declRef.As()) + { + emitSimpleSubscriptCallExpr(callExpr, outerPrec); + return; + } + } // Once we've ruled out constructor calls, we can move on -- cgit v1.2.3 From ccea5702442a7a8303e6735a038be86939c1ce7a Mon Sep 17 00:00:00 2001 From: Tim Foley Date: Tue, 7 Nov 2017 10:22:53 -0800 Subject: Emit pointer-type parameters as out params The IR encodes `out` and `in out` function parameters as pointer types, so the emit logic needs to handle it. We had code to handle translation of pointers types into `out` declarations for function *declarations* but weren't handling it for function *definitions*. This change unifies the logic so that it is shared by function definitions and decalrations. This change does *not* deal with the following issues that need to be addressed sometime soon-ish: - We currently always translate pointers into `out`, even if they should be `in out`. This is obviously wrong. - If/when we eventually have targets that support true pointers (e.g., CUDA, NVIDIA OpenGL, etc.) we'll need a way to tell the difference between an `in` pointer parameter, and an `out` parameter. Both of these issues are meant to be addressed by having a few special cases of pointer types, for the `out` and `in out` cases, and only translating those (not all pointers). We need to plumb those through the IR more completely, but I'm not dealing with that here. --- source/slang/emit.cpp | 51 ++++++++++++++++++++++++++++++--------------------- 1 file changed, 30 insertions(+), 21 deletions(-) (limited to 'source') diff --git a/source/slang/emit.cpp b/source/slang/emit.cpp index c67bb7b29..617e25d71 100644 --- a/source/slang/emit.cpp +++ b/source/slang/emit.cpp @@ -5698,7 +5698,8 @@ emitDeclImpl(decl, nullptr); emit(", "); auto paramName = getIRName(pp); - emitIRType(ctx, pp->getType(), paramName); + auto paramType = pp->getType(); + emitIRParamType(ctx, paramType, paramName); emitIRSemantics(ctx, pp); } @@ -5724,6 +5725,33 @@ emitDeclImpl(decl, nullptr); } } + void emitIRParamType( + EmitContext* ctx, + Type* type, + String const& name) + { + // An `out` or `inout` parameter will have been + // encoded as a parameter of pointer type, so + // we need to decode that here. + // + if( auto ptrType = type->As() ) + { + // TODO: we need a way to distinguish `out` + // from `inout`. The easiest way to do + // that might be to have each be a distinct + // sub-case of `IRPtrType` - this would also + // ensure that they can be distinguished from + // real pointers when the user means to use + // them. + + emit("out "); + + type = ptrType->getValueType(); + } + + emitIRType(ctx, type, name); + } + void emitIRFuncDecl( EmitContext* ctx, IRFunc* func) @@ -5771,26 +5799,7 @@ emitDeclImpl(decl, nullptr); paramName.append(pp); auto paramType = funcType->getParamType(pp); - // An `out` or `inout` parameter will have been - // encoded as a parameter of pointer type, so - // we need to decode that here. - // - if( auto ptrType = paramType->As() ) - { - // TODO: we need a way to distinguish `out` - // from `inout`. The easiest way to do - // that might be to have each be a distinct - // sub-case of `IRPtrType` - this would also - // ensure that they can be distinguished from - // real pointers when the user means to use - // them. - - emit("out "); - - paramType = ptrType->getValueType(); - } - - emitIRType(ctx, paramType, paramName); + emitIRParamType(ctx, paramType, paramName); } emit(");\n"); } -- cgit v1.2.3