diff options
| -rw-r--r-- | source/slang/hlsl.meta.slang | 583 | ||||
| -rw-r--r-- | source/slang/slang-check-stmt.cpp | 7 | ||||
| -rw-r--r-- | source/slang/slang-emit-glsl.cpp | 12 | ||||
| -rw-r--r-- | source/slang/slang-emit-hlsl.cpp | 5 | ||||
| -rw-r--r-- | source/slang/slang-intrinsic-expand.cpp | 22 | ||||
| -rw-r--r-- | source/slang/slang-ir-inst-defs.h | 2 | ||||
| -rw-r--r-- | source/slang/slang-ir-spirv-legalize.cpp | 62 | ||||
| -rw-r--r-- | source/slang/slang-lower-to-ir.cpp | 4 | ||||
| -rw-r--r-- | source/slang/slang-parser.cpp | 3 | ||||
| -rw-r--r-- | tests/gpu-feature/texture/query/footprint/nv-shader-texture-footprint-simple.slang | 3 | ||||
| -rw-r--r-- | tests/gpu-feature/texture/query/footprint/nv-shader-texture-footprint.slang | 4 |
11 files changed, 467 insertions, 240 deletions
diff --git a/source/slang/hlsl.meta.slang b/source/slang/hlsl.meta.slang index b424b868e..2bac47fd6 100644 --- a/source/slang/hlsl.meta.slang +++ b/source/slang/hlsl.meta.slang @@ -2,10 +2,6 @@ typedef uint UINT; -// Access float2/float3 as a float3 -[ForceInline] float3 __asFloat3(float2 v) { return float3(v, 0); } -[ForceInline] float3 __asFloat3(float3 v) { return v; } - __generic<T> __intrinsic_op($(kIROp_StructuredBufferGetDimensions)) uint2 __structuredBufferGetDimensions(AppendStructuredBuffer<T> buffer); @@ -11782,6 +11778,27 @@ func saturated_cooperation_using<A, B, C>( } +${ +// The NVAPI operations are defined to take the space/register +// indices of their texture and sampler parameters, rather than +// taking the texture/sampler objects directly. +// +// In order to support this approach, we need intrinsics that +// can magically fetch the binding information for a resource. +// +// TODO: These operations are kind of *screaming* for us to +// have a built-in `interface` that all of the opaque resource +// types conform to, so that we can define builtins that work +// for any resource type. +} + +__intrinsic_op($(kIROp_GetRegisterSpace)) uint __getRegisterSpace<T, Shape: __ITextureShape, let isArray:int, let isMS:int, let sampleCount:int, let access:int, let isShadow:int, let isCombined:int, let format:int>(__TextureImpl<T,Shape,isArray,isMS,sampleCount,access,isShadow,isCombined,format> texture); +__intrinsic_op($(kIROp_GetRegisterSpace)) uint __getRegisterSpace(SamplerState sampler); + +__intrinsic_op($(kIROp_GetRegisterIndex)) uint __getRegisterIndex<T, Shape: __ITextureShape, let isArray:int, let isMS:int, let sampleCount:int, let access:int, let isShadow:int, let isCombined:int, let format:int>(__TextureImpl<T,Shape,isArray,isMS,sampleCount,access,isShadow,isCombined,format> texture); +__intrinsic_op($(kIROp_GetRegisterIndex)) uint __getRegisterIndex(SamplerState sampler); + + ${{{{ // // Texture Footprint Queries @@ -11795,23 +11812,6 @@ ${{{{ // use a meta-loop to deduplicate the code for the two // cases. // -static const struct FootprintTextureShape -{ - int rank; - char const* suffix; - char const* texelIndexType; - char const* sampleCoordsType; -} kFootprintTextureShapes[] = -{ - { 2, "2D", "uint2", "float2" }, - { 3, "3D", "uint3", "float3" }, -}; -for(auto shape : kFootprintTextureShapes) -{ - auto ND = shape.suffix; - auto anchorType = shape.texelIndexType; - auto offsetType = shape.texelIndexType; - auto coordsType = shape.sampleCoordsType; // A footprint query yields a data structure // that describes blocks of texels that @@ -11833,14 +11833,45 @@ for(auto shape : kFootprintTextureShapes) // }}}} -__glsl_version(450) -__glsl_extension(GL_NV_shader_texture_footprint) -__target_intrinsic(glsl, gl_TextureFootprint$(ND)NV) -__target_intrinsic(hlsl, uint4) -struct __TextureFootprintData$(ND) +[__NoSideEffect] +[__requiresNVAPI] +vector<uint, ND> __textureFootprintGetAnchor<let ND:int>(__TextureFootprintData<ND> data, int nd) +{ + __target_switch + { + case hlsl: + __intrinsic_asm "NvFootprintExtractAnchorTileLoc$!1D($0)"; + case glsl: + __intrinsic_asm "$0.anchor"; + case spirv: + return spirv_asm { + result:$$vector<uint,ND> = OpCompositeExtract $data 1; + }; + } +} + +[__NoSideEffect] +[__requiresNVAPI] +vector<uint, ND> __textureFootprintGetOffset<let ND:int>(__TextureFootprintData<ND> data, int nd) { - typealias Anchor = $(anchorType); - typealias Offset = $(offsetType); + __target_switch + { + case hlsl: + __intrinsic_asm "NvFootprintExtractOffset$!1D($0)"; + case glsl: + __intrinsic_asm "$0.offset"; + case spirv: + return spirv_asm { + result:$$vector<uint,ND> = OpCompositeExtract $data 2; + }; + } +} + +__intrinsic_type($(kIROp_TextureFootprintType)) +struct __TextureFootprintData<let ND:int> +{ + typealias Anchor = vector<uint, ND>; + typealias Offset = vector<uint, ND>; typealias Mask = uint2; typealias LOD = uint; typealias Granularity = uint; @@ -11849,49 +11880,80 @@ struct __TextureFootprintData$(ND) { [__NoSideEffect] [__requiresNVAPI] - __target_intrinsic(hlsl, NvFootprintExtractAnchorTileLoc$(ND)) - __target_intrinsic(glsl, "$0.anchor") - get; + [ForceInline] + get { return __textureFootprintGetAnchor(this, ND); } } property offset : Offset { [__NoSideEffect] [__requiresNVAPI] - __target_intrinsic(hlsl, NvFootprintExtractOffset$(ND)) - __target_intrinsic(glsl, "$0.offset") - get; + [ForceInline] + get { return __textureFootprintGetOffset(this, ND); } } property mask : Mask { [__NoSideEffect] [__requiresNVAPI] - __target_intrinsic(hlsl, NvFootprintExtractBitmask) - __target_intrinsic(glsl, "$0.mask") - get; + get + { + __target_switch + { + case hlsl: + __intrinsic_asm "NvFootprintExtractBitmask"; + case glsl: + __intrinsic_asm "$0.mask"; + case spirv: + return spirv_asm { + result:$$Mask = OpCompositeExtract $this 3; + }; + } + } } property lod : LOD { [__NoSideEffect] [__requiresNVAPI] - __target_intrinsic(hlsl, NvFootprintExtractLOD) - __target_intrinsic(glsl, "$0.lod") - get; + get + { + __target_switch + { + case hlsl: + __intrinsic_asm "NvFootprintExtractLOD"; + case glsl: + __intrinsic_asm "$0.lod"; + case spirv: + return spirv_asm { + result:$$LOD = OpCompositeExtract $this 4; + }; + } + } } property granularity : Granularity { [__NoSideEffect] [__requiresNVAPI] - __target_intrinsic(hlsl, NvFootprintExtractReturnGran) - __target_intrinsic(glsl, "$0.granularity") - get; + get + { + __target_switch + { + case hlsl: + __intrinsic_asm "NvFootprintExtractReturnGran"; + case glsl: + __intrinsic_asm "$0.granularity"; + case spirv: + return spirv_asm { + result:$$Granularity = OpCompositeExtract $this 5; + }; + } + } } } -struct TextureFootprint$(ND) : __TextureFootprintData$(ND) +struct TextureFootprint<let ND:int> : __TextureFootprintData<ND> { bool _isSingleLevel; @@ -11905,27 +11967,8 @@ struct TextureFootprint$(ND) : __TextureFootprintData$(ND) } } -${ -// The NVAPI operations are defined to take the space/register -// indices of their texture and sampler parameters, rather than -// taking the texture/sampler objects directly. -// -// In order to support this approach, we need intrinsics that -// can magically fetch the binding information for a resource. -// -// TODO: These operations are kind of *screaming* for us to -// have a built-in `interface` that all of the opaque resource -// types conform to, so that we can define builtins that work -// for any resource type. -} - -__intrinsic_op($(kIROp_GetRegisterSpace)) uint __getRegisterSpace<T>(Texture2D<T> texture); -__intrinsic_op($(kIROp_GetRegisterSpace)) uint __getRegisterSpace<T>(Texture3D<T> texture); -__intrinsic_op($(kIROp_GetRegisterSpace)) uint __getRegisterSpace(SamplerState sampler); - -__intrinsic_op($(kIROp_GetRegisterIndex)) uint __getRegisterIndex<T>(Texture2D<T> texture); -__intrinsic_op($(kIROp_GetRegisterIndex)) uint __getRegisterIndex<T>(Texture3D<T> texture); -__intrinsic_op($(kIROp_GetRegisterIndex)) uint __getRegisterIndex(SamplerState sampler); +typealias TextureFootprint2D = TextureFootprint<2>; +typealias TextureFootprint3D = TextureFootprint<3>; ${ // We define the new operations via an `extension` @@ -11933,8 +11976,8 @@ ${ // further clutter the original type declarations. } -__generic<T> -extension Texture$(ND)<T> +__generic<T, Shape: __ITextureShape, let sampleCount:int, let isShadow:int, let format:int> +extension __TextureImpl<T,Shape,0,0,sampleCount,0,isShadow,0,format> { ${ // We introduce a few convenience type aliases here, @@ -11948,9 +11991,9 @@ ${ // defined on the base texture types, rather than via // this `extension`. } - typealias Coords = $(coordsType); - typealias Footprint = TextureFootprint$(ND); - typealias __FootprintData = __TextureFootprintData$(ND); + typealias Coords = vector<float, Shape.dimensions>; + typealias Footprint = TextureFootprint<Shape.dimensions>; + typealias __FootprintData = __TextureFootprintData<Shape.dimensions>; typealias FootprintGranularity = Footprint.Granularity; ${ @@ -11971,27 +12014,55 @@ ${ [__NoSideEffect] __glsl_version(450) __glsl_extension(GL_NV_shader_texture_footprint) - __target_intrinsic(glsl, - "textureFootprintNV($p, $*2)") bool __queryFootprintGLSL( SamplerState sampler, Coords coords, int granularity, bool useCoarseLevel, - out __FootprintData footprint); + out __FootprintData footprint) + { + __target_switch + { + case glsl: + __intrinsic_asm "textureFootprintNV($p, $*2)"; + case spirv: + return spirv_asm { + OpCapability ImageFootprintNV; + OpExtension "SPV_NV_shader_image_footprint"; + %sampledImage:__sampledImageType(this) = OpSampledImage $this $sampler; + %resultVal:$$__FootprintData = OpImageSampleFootprintNV %sampledImage $coords $granularity $useCoarseLevel; + OpStore &footprint %resultVal; + result:$$bool = OpCompositeExtract %resultVal 0; + }; + } + } [__NoSideEffect] __glsl_version(450) __glsl_extension(GL_NV_shader_texture_footprint) - __target_intrinsic(glsl, - "textureFootprintNV($p, $*2)") bool __queryFootprintGLSL( SamplerState sampler, Coords coords, int granularity, bool useCoarseLevel, out __FootprintData footprint, - float bias); + float bias) + { + __target_switch + { + case glsl: + __intrinsic_asm "textureFootprintNV($p, $*2)"; + case spirv: + return spirv_asm { + OpCapability ImageFootprintNV; + OpExtension "SPV_NV_shader_image_footprint"; + %sampledImage:__sampledImageType(this) = OpSampledImage $this $sampler; + %resultVal:$$__FootprintData = OpImageSampleFootprintNV %sampledImage $coords $granularity $useCoarseLevel Bias $bias; + OpStore &footprint %resultVal; + result:$$bool = OpCompositeExtract %resultVal 0; + }; + } + } [__NoSideEffect] __glsl_version(450) @@ -12005,14 +12076,29 @@ ${ float lodClamp, int granularity, bool useCoarseLevel, - out __FootprintData footprint); + out __FootprintData footprint) + { + __target_switch + { + case glsl: + __intrinsic_asm "textureFootprintClampNV($p, $*2)"; + case spirv: + return spirv_asm { + OpCapability ImageFootprintNV; + OpCapability MinLod; + OpExtension "SPV_NV_shader_image_footprint"; + %sampledImage:__sampledImageType(this) = OpSampledImage $this $sampler; + %resultVal:$$__FootprintData = OpImageSampleFootprintNV %sampledImage $coords $granularity $useCoarseLevel MinLod $lodClamp; + OpStore &footprint %resultVal; + result:$$bool = OpCompositeExtract %resultVal 0; + }; + } + } [__NoSideEffect] __glsl_version(450) __glsl_extension(GL_NV_shader_texture_footprint) __glsl_extension(GL_ARB_sparse_texture_clamp) - __target_intrinsic(glsl, - "textureFootprintClampNV($p, $*2)") bool __queryFootprintClampGLSL( SamplerState sampler, Coords coords, @@ -12020,13 +12106,28 @@ ${ int granularity, bool useCoarseLevel, out __FootprintData footprint, - float bias); + float bias) + { + __target_switch + { + case glsl: + __intrinsic_asm "textureFootprintClampNV($p, $*2)"; + case spirv: + return spirv_asm { + OpCapability ImageFootprintNV; + OpCapability MinLod; + OpExtension "SPV_NV_shader_image_footprint"; + %sampledImage:__sampledImageType(this) = OpSampledImage $this $sampler; + %resultVal:$$__FootprintData = OpImageSampleFootprintNV %sampledImage $coords $granularity $useCoarseLevel Bias|MinLod $bias $lodClamp; + OpStore &footprint %resultVal; + result:$$bool = OpCompositeExtract %resultVal 0; + }; + } + } [__NoSideEffect] __glsl_version(450) __glsl_extension(GL_NV_shader_texture_footprint) - __target_intrinsic(glsl, - "textureFootprintLodNV($p, $*2)") [__requiresNVAPI] bool __queryFootprintLodGLSL( SamplerState sampler, @@ -12034,18 +12135,31 @@ ${ float lod, int granularity, bool useCoarseLevel, - out __FootprintData footprint); + out __FootprintData footprint) + { + __target_switch + { + case glsl: + __intrinsic_asm "textureFootprintLodNV($p, $*2)"; + case spirv: + return spirv_asm { + OpCapability ImageFootprintNV; + OpExtension "SPV_NV_shader_image_footprint"; + %sampledImage:__sampledImageType(this) = OpSampledImage $this $sampler; + %resultVal:$$__FootprintData = OpImageSampleFootprintNV %sampledImage $coords $granularity $useCoarseLevel Lod $lod; + OpStore &footprint %resultVal; + result:$$bool = OpCompositeExtract %resultVal 0; + }; + } + } ${{{ // Texture sampling with gradient is only available for 2D textures. - if(shape.rank == 2) { }}} [__NoSideEffect] __glsl_version(450) __glsl_extension(GL_NV_shader_texture_footprint) - __target_intrinsic(glsl, - "textureFootprintGradNV($p, $*2)") [__requiresNVAPI] bool __queryFootprintGradGLSL( SamplerState sampler, @@ -12054,14 +12168,28 @@ ${{{ Coords dy, int granularity, bool useCoarseLevel, - out __FootprintData footprint); + out __FootprintData footprint) + { + __target_switch + { + case glsl: + __intrinsic_asm "textureFootprintGradNV($p, $*2)"; + case spirv: + return spirv_asm { + OpCapability ImageFootprintNV; + OpExtension "SPV_NV_shader_image_footprint"; + %sampledImage:__sampledImageType(this) = OpSampledImage $this $sampler; + %resultVal:$$__FootprintData = OpImageSampleFootprintNV %sampledImage $coords $granularity $useCoarseLevel Grad $dx $dy; + OpStore &footprint %resultVal; + result:$$bool = OpCompositeExtract %resultVal 0; + }; + } + } [__NoSideEffect] __glsl_version(450) __glsl_extension(GL_NV_shader_texture_footprint) __glsl_extension(GL_ARB_sparse_texture_clamp) - __target_intrinsic(glsl, - "textureFootprintGradClampNV($p, $*2)") bool __queryFootprintGradClampGLSL( SamplerState sampler, Coords coords, @@ -12070,9 +12198,26 @@ ${{{ float lodClamp, int granularity, bool useCoarseLevel, - out __FootprintData footprint); -${{{ + out __FootprintData footprint) + { + __target_switch + { + case glsl: + __intrinsic_asm "textureFootprintGradClampNV($p, $*2)"; + case spirv: + return spirv_asm { + OpCapability ImageFootprintNV; + OpCapability MinLod; + OpExtension "SPV_NV_shader_image_footprint"; + %sampledImage:__sampledImageType(this) = OpSampledImage $this $sampler; + %resultVal:$$__FootprintData = OpImageSampleFootprintNV %sampledImage $coords $granularity $useCoarseLevel Grad|MinLod $dx $dy $lodClamp; + OpStore &footprint %resultVal; + result:$$bool = OpCompositeExtract %resultVal 0; + }; + } } +${{{ + // End texture2D specific functions. }}} @@ -12113,8 +12258,9 @@ for(auto levelChoice : kLevelChoices) [__NoSideEffect] [__requiresNVAPI] __target_intrinsic(hlsl, - "NvFootprint$(CoarseOrFine)($0, $1, $2, $3, NV_EXTN_TEXTURE_$(ND), $*4)") + "NvFootprint$(CoarseOrFine)($1, $2, $3, $4, NV_EXTN_TEXTURE_$!0D, $*5)") static __FootprintData __queryFootprint$(CoarseOrFine)NVAPI( + int nd, uint textureSpace, uint textureIndex, uint samplerSpace, @@ -12126,8 +12272,9 @@ for(auto levelChoice : kLevelChoices) [__NoSideEffect] [__requiresNVAPI] __target_intrinsic(hlsl, - "NvFootprint$(CoarseOrFine)Bias($0, $1, $2, $3, NV_EXTN_TEXTURE_$(ND), $*4)") + "NvFootprint$(CoarseOrFine)Bias($1, $2, $3, $4, NV_EXTN_TEXTURE_$!0D, $*5)") static __FootprintData __queryFootprint$(CoarseOrFine)BiasNVAPI( + int nd, uint textureSpace, uint textureIndex, uint samplerSpace, @@ -12140,8 +12287,9 @@ for(auto levelChoice : kLevelChoices) [__NoSideEffect] [__requiresNVAPI] __target_intrinsic(hlsl, - "NvFootprint$(CoarseOrFine)Level($0, $1, $2, $3, NV_EXTN_TEXTURE_$(ND), $*4)") + "NvFootprint$(CoarseOrFine)Level($1, $2, $3, $4, NV_EXTN_TEXTURE_$!0D, $*5)") static __FootprintData __queryFootprint$(CoarseOrFine)LevelNVAPI( + int nd, uint textureSpace, uint textureIndex, uint samplerSpace, @@ -12151,15 +12299,12 @@ for(auto levelChoice : kLevelChoices) float lod, out uint isSingleLod); -${{{ - // Texture sampling with gradient is only available for 2D textures. - if(shape.rank == 2) { -}}} [__NoSideEffect] [__requiresNVAPI] __target_intrinsic(hlsl, - "NvFootprint$(CoarseOrFine)Grad($0, $1, $2, $3, NV_EXTN_TEXTURE_$(ND), $*4)") + "NvFootprint$(CoarseOrFine)Grad($1, $2, $3, $4, NV_EXTN_TEXTURE_$!0D, $*5)") static __FootprintData __queryFootprint$(CoarseOrFine)GradNVAPI( + int nd, uint textureSpace, uint textureIndex, uint samplerSpace, @@ -12169,9 +12314,6 @@ ${{{ float3 dx, float3 dy, out uint isSingleLod); -${{{ - } -}}} ${ // We now define the portable operations that will be officially @@ -12182,6 +12324,14 @@ ${ // Some function variations are only available with one extension // or the other, so we try our best to only define them where // each is available. +// +// Note that these functions cannot be marked as [ForceInline] for now +// because the texture resource may get removed after DCE, since the only +// use of those resources are done through __GetRegisterIndex/Space, which is +// replaced early with their binding slot in the compilation process. +// Not inlining these function is a quick way to make sure the texture always +// has live uses. +// } /// Query the footprint that would be accessed by a texture sampling operation. @@ -12192,58 +12342,29 @@ ${ /// t.Sample(sampler, coords); /// [__NoSideEffect] - __specialized_for_target(glsl) - Footprint queryFootprint$(CoarseOrFine)( - FootprintGranularity granularity, - SamplerState sampler, - Coords coords) - { - Footprint footprint; - footprint._isSingleLevel = __queryFootprintGLSL(sampler, coords, granularity, $(isCoarseVal), footprint); - return footprint; - } - - /// Query the footprint that would be accessed by a texture sampling operation. - /// - /// This operation queries the footprint that would be accessed - /// by a comparable call to: - /// - /// t.Sample(sampler, coords); - /// - [__NoSideEffect] - __specialized_for_target(hlsl) Footprint queryFootprint$(CoarseOrFine)( FootprintGranularity granularity, SamplerState sampler, Coords coords) { - uint isSingleLod = 0; - Footprint footprint = {__queryFootprint$(CoarseOrFine)NVAPI( - __getRegisterSpace(this), __getRegisterIndex(this), - __getRegisterSpace(sampler), __getRegisterIndex(sampler), - __asFloat3(coords), granularity, /* out */isSingleLod), false}; - footprint._isSingleLevel = (isSingleLod != 0); - return footprint; - } + __target_switch + { + case glsl: + case spirv: + Footprint footprint; + footprint._isSingleLevel = __queryFootprintGLSL(sampler, coords, granularity, $(isCoarseVal), footprint); + return footprint; - /// Query the footprint that would be accessed by a texture sampling operation. - /// - /// This operation queries the footprint that would be accessed - /// by a comparable call to: - /// - /// t.SampleBias(sampler, coords, lodBias); - /// - [__NoSideEffect] - __specialized_for_target(glsl) - Footprint queryFootprint$(CoarseOrFine)Bias( - FootprintGranularity granularity, - SamplerState sampler, - Coords coords, - float lodBias) - { - Footprint footprint; - footprint._isSingleLevel = __queryFootprintGLSL(sampler, coords, granularity, $(isCoarseVal), footprint, lodBias); - return footprint; + case hlsl: + uint isSingleLod = 0; + Footprint footprint = {__queryFootprint$(CoarseOrFine)NVAPI( + Shape.dimensions, + __getRegisterSpace(this), __getRegisterIndex(this), + __getRegisterSpace(sampler), __getRegisterIndex(sampler), + __vectorReshape<3>(coords), granularity, /* out */isSingleLod), false}; + footprint._isSingleLevel = (isSingleLod != 0); + return footprint; + } } /// Query the footprint that would be accessed by a texture sampling operation. @@ -12254,21 +12375,30 @@ ${ /// t.SampleBias(sampler, coords, lodBias); /// [__NoSideEffect] - __specialized_for_target(hlsl) Footprint queryFootprint$(CoarseOrFine)Bias( FootprintGranularity granularity, SamplerState sampler, Coords coords, float lodBias) { - uint isSingleLod = 0; - Footprint footprint = {__queryFootprint$(CoarseOrFine)BiasNVAPI( - __getRegisterSpace(this), __getRegisterIndex(this), - __getRegisterSpace(sampler), __getRegisterIndex(sampler), - __asFloat3(coords), granularity, lodBias, /* out */isSingleLod), false}; + __target_switch + { + case glsl: + case spirv: + Footprint footprint; + footprint._isSingleLevel = __queryFootprintGLSL(sampler, coords, granularity, $(isCoarseVal), footprint, lodBias); + return footprint; + case hlsl: + uint isSingleLod = 0; + Footprint footprint = {__queryFootprint$(CoarseOrFine)BiasNVAPI( + Shape.dimensions, + __getRegisterSpace(this), __getRegisterIndex(this), + __getRegisterSpace(sampler), __getRegisterIndex(sampler), + __vectorReshape<3>(coords), granularity, lodBias, /* out */isSingleLod), false}; - footprint._isSingleLevel = (isSingleLod != 0); - return footprint; + footprint._isSingleLevel = (isSingleLod != 0); + return footprint; + } } /// Query the footprint that would be accessed by a texture sampling operation. @@ -12279,16 +12409,20 @@ ${ /// t.SampleClamp(sampler, coords, lodClamp); /// [__NoSideEffect] - __specialized_for_target(glsl) Footprint queryFootprint$(CoarseOrFine)Clamp( FootprintGranularity granularity, SamplerState sampler, Coords coords, float lodClamp) { - Footprint footprint; - footprint._isSingleLevel = __queryFootprintClampGLSL(sampler, coords, lodClamp, granularity, $(isCoarseVal), footprint); - return footprint; + __target_switch + { + case glsl: + case spirv: + Footprint footprint; + footprint._isSingleLevel = __queryFootprintClampGLSL(sampler, coords, lodClamp, granularity, $(isCoarseVal), footprint); + return footprint; + } } /// Query the footprint that would be accessed by a texture sampling operation. @@ -12299,7 +12433,6 @@ ${ /// t.SampleBiasClamp(sampler, coords, lodBias, lodClamp); /// [__NoSideEffect] - __specialized_for_target(glsl) Footprint queryFootprint$(CoarseOrFine)BiasClamp( FootprintGranularity granularity, SamplerState sampler, @@ -12307,29 +12440,14 @@ ${ float lodBias, float lodClamp) { - Footprint footprint; - footprint._isSingleLevel = __queryFootprintClampGLSL(sampler, coords, lodClamp, granularity, $(isCoarseVal), footprint, lodBias); - return footprint; - } - - /// Query the footprint that would be accessed by a texture sampling operation. - /// - /// This operation queries the footprint that would be accessed - /// by a comparable call to: - /// - /// t.SampleLevel(sampler, coords, lod); - /// - [__NoSideEffect] - __specialized_for_target(glsl) - Footprint queryFootprint$(CoarseOrFine)Level( - FootprintGranularity granularity, - SamplerState sampler, - Coords coords, - float lod) - { - Footprint footprint; - footprint._isSingleLevel = __queryFootprintLodGLSL(sampler, coords, lod, granularity, $(isCoarseVal), footprint); - return footprint; + __target_switch + { + case glsl: + case spirv: + Footprint footprint; + footprint._isSingleLevel = __queryFootprintClampGLSL(sampler, coords, lodClamp, granularity, $(isCoarseVal), footprint, lodBias); + return footprint; + } } /// Query the footprint that would be accessed by a texture sampling operation. @@ -12340,27 +12458,34 @@ ${ /// t.SampleLevel(sampler, coords, lod); /// [__NoSideEffect] - __specialized_for_target(hlsl) Footprint queryFootprint$(CoarseOrFine)Level( FootprintGranularity granularity, SamplerState sampler, Coords coords, float lod) { - uint isSingleLod = 0; - Footprint footprint = {__queryFootprint$(CoarseOrFine)LevelNVAPI( - __getRegisterSpace(this), __getRegisterIndex(this), - __getRegisterSpace(sampler), __getRegisterIndex(sampler), - __asFloat3(coords), granularity, lod, /* out */isSingleLod), false}; + __target_switch + { + case glsl: + case spirv: + Footprint footprint; + footprint._isSingleLevel = __queryFootprintLodGLSL(sampler, coords, lod, granularity, $(isCoarseVal), footprint); + return footprint; + case hlsl: + uint isSingleLod = 0; + Footprint footprint = {__queryFootprint$(CoarseOrFine)LevelNVAPI( + Shape.dimensions, + __getRegisterSpace(this), __getRegisterIndex(this), + __getRegisterSpace(sampler), __getRegisterIndex(sampler), + __vectorReshape<3>(coords), granularity, lod, /* out */isSingleLod), false}; - footprint._isSingleLevel = (isSingleLod != 0); - return footprint; + footprint._isSingleLevel = (isSingleLod != 0); + return footprint; + } } - ${{{ - // Texture sampling with gradient is only available for 2D textures. - if(shape.rank == 2) { + // TODO: Texture sampling with gradient is only available for 2D textures. }}} /// Query the footprint that would be accessed by a texture sampling operation. @@ -12370,29 +12495,7 @@ ${{{ /// /// t.SampleGrad(sampler, coords, dx, dy); /// - [__NoSideEffect] - __specialized_for_target(glsl) - Footprint queryFootprint$(CoarseOrFine)Grad( - FootprintGranularity granularity, - SamplerState sampler, - Coords coords, - Coords dx, - Coords dy) - { - Footprint footprint; - footprint._isSingleLevel = __queryFootprintGradGLSL(sampler, coords, dx, dy, granularity, $(isCoarseVal), footprint); - return footprint; - } - - /// Query the footprint that would be accessed by a texture sampling operation. - /// - /// This operation queries the footprint that would be accessed - /// by a comparable call to: - /// - /// t.SampleGrad(sampler, coords, dx, dy); - /// - [__NoSideEffect] - __specialized_for_target(hlsl) + [__NoSideEffect] [ForceInline] Footprint queryFootprint$(CoarseOrFine)Grad( FootprintGranularity granularity, SamplerState sampler, @@ -12400,14 +12503,24 @@ ${{{ Coords dx, Coords dy) { - uint isSingleLod = 0; - Footprint footprint = {__queryFootprint$(CoarseOrFine)GradNVAPI( - __getRegisterSpace(this), __getRegisterIndex(this), - __getRegisterSpace(sampler), __getRegisterIndex(sampler), - __asFloat3(coords), granularity, __asFloat3(dx), __asFloat3(dy), /* out */isSingleLod), false}; + __target_switch + { + case glsl: + case spirv: + Footprint footprint; + footprint._isSingleLevel = __queryFootprintGradGLSL(sampler, coords, dx, dy, granularity, $(isCoarseVal), footprint); + return footprint; + case hlsl: + uint isSingleLod = 0; + Footprint footprint = {__queryFootprint$(CoarseOrFine)GradNVAPI( + Shape.dimensions, + __getRegisterSpace(this), __getRegisterIndex(this), + __getRegisterSpace(sampler), __getRegisterIndex(sampler), + __vectorReshape<3>(coords), granularity, __vectorReshape<3>(dx), __vectorReshape<3>(dy), /* out */isSingleLod), false}; - footprint._isSingleLevel = (isSingleLod != 0); - return footprint; + footprint._isSingleLevel = (isSingleLod != 0); + return footprint; + } } /// Query the footprint that would be accessed by a texture sampling operation. @@ -12417,8 +12530,7 @@ ${{{ /// /// t.SampleGradClamp(sampler, coords, dx, dy, lodClamp); /// - [__NoSideEffect] - __specialized_for_target(glsl) + [__NoSideEffect][ForceInline] Footprint queryFootprint$(CoarseOrFine)GradClamp( FootprintGranularity granularity, SamplerState sampler, @@ -12427,13 +12539,18 @@ ${{{ Coords dy, float lodClamp) { - Footprint footprint; - footprint._isSingleLevel = __queryFootprintGradClampGLSL(sampler, coords, dx, dy, lodClamp, granularity, $(isCoarseVal), footprint); - return footprint; + __target_switch + { + case glsl: + case spirv: + Footprint footprint; + footprint._isSingleLevel = __queryFootprintGradClampGLSL(sampler, coords, dx, dy, lodClamp, granularity, $(isCoarseVal), footprint); + return footprint; + } } ${{{ - } // if(shape.rank == 2) + // TODO: end texture2D specific functions. }}} ${{{{ @@ -12442,10 +12559,6 @@ ${{{{ } // extension -${{{{ -} -}}}} - // Buffer Pointer __generic<T, let Alignment : int = 16> diff --git a/source/slang/slang-check-stmt.cpp b/source/slang/slang-check-stmt.cpp index bbe3e51bd..b2c58ccc7 100644 --- a/source/slang/slang-check-stmt.cpp +++ b/source/slang/slang-check-stmt.cpp @@ -267,9 +267,14 @@ namespace Slang void SemanticsStmtVisitor::visitTargetSwitchStmt(TargetSwitchStmt* stmt) { WithOuterStmt subContext(this, stmt); - + HashSet<Stmt*> checkedStmt; for (auto caseStmt : stmt->targetCases) + { + if (checkedStmt.contains(caseStmt->body)) + continue; subContext.checkStmt(caseStmt); + checkedStmt.add(caseStmt->body); + } } void SemanticsStmtVisitor::visitTargetCaseStmt(TargetCaseStmt* stmt) diff --git a/source/slang/slang-emit-glsl.cpp b/source/slang/slang-emit-glsl.cpp index bbfefc75c..0fc54ca1f 100644 --- a/source/slang/slang-emit-glsl.cpp +++ b/source/slang/slang-emit-glsl.cpp @@ -2347,6 +2347,18 @@ void GLSLSourceEmitter::emitSimpleTypeImpl(IRType* type) m_writer->emit("hitObjectNV"); return; } + case kIROp_TextureFootprintType: + { + m_glslExtensionTracker->requireExtension(UnownedStringSlice("GL_NV_shader_texture_footprint")); + m_glslExtensionTracker->requireVersion(ProfileVersion::GLSL_450); + + m_writer->emit("gl_TextureFootprint"); + auto intLit = as<IRIntLit>(type->getOperand(0)); + if (intLit) + m_writer->emit(intLit->getValue()); + m_writer->emit("DNV"); + return; + } default: break; } diff --git a/source/slang/slang-emit-hlsl.cpp b/source/slang/slang-emit-hlsl.cpp index 9b333c281..416e8b0a1 100644 --- a/source/slang/slang-emit-hlsl.cpp +++ b/source/slang/slang-emit-hlsl.cpp @@ -937,6 +937,11 @@ void HLSLSourceEmitter::emitSimpleTypeImpl(IRType* type) m_writer->emit("NvHitObject"); return; } + case kIROp_TextureFootprintType: + { + m_writer->emit("uint4"); + return; + } default: break; } diff --git a/source/slang/slang-intrinsic-expand.cpp b/source/slang/slang-intrinsic-expand.cpp index d65fdf8bb..b96c2657d 100644 --- a/source/slang/slang-intrinsic-expand.cpp +++ b/source/slang/slang-intrinsic-expand.cpp @@ -818,8 +818,28 @@ const char* IntrinsicExpandContext::_emitSpecial(const char* cursor) if (vectorSize <= 4) m_writer->emitChar(swizzleNames[vectorSize - 1]); } + break; + } + case '!': + { + // Emit a literal directly without any prefix/postfix/casts. + Index argIndex = parseNat() + m_argIndexOffset; + SLANG_RELEASE_ASSERT((0 <= argIndex) && (argIndex < m_argCount)); + auto arg = m_args[argIndex]; + if (auto intLit = as<IRIntLit>(arg.get())) + { + m_writer->emitInt64(intLit->getValue()); + } + else if (auto stringLit = as<IRStringLit>(arg.get())) + { + m_writer->emit(stringLit->getStringSlice()); + } + else + { + SLANG_UNEXPECTED("unexpected literal argument in intrinsic call."); + } + break; } - break; default: SLANG_UNEXPECTED("bad format in intrinsic definition"); diff --git a/source/slang/slang-ir-inst-defs.h b/source/slang/slang-ir-inst-defs.h index 496c195d7..cce31ed61 100644 --- a/source/slang/slang-ir-inst-defs.h +++ b/source/slang/slang-ir-inst-defs.h @@ -133,6 +133,8 @@ INST(Nop, nop, 0, 0) INST(SamplerComparisonStateType, SamplerComparisonState, 0, HOISTABLE) INST_RANGE(SamplerStateTypeBase, SamplerStateType, SamplerComparisonStateType) + INST(TextureFootprintType, TextureFootprintType, 1, HOISTABLE) + INST(TextureShape1DType, TextureShape1DType, 0, HOISTABLE) INST(TextureShape2DType, TextureShape1DType, 0, HOISTABLE) INST(TextureShape3DType, TextureShape1DType, 0, HOISTABLE) diff --git a/source/slang/slang-ir-spirv-legalize.cpp b/source/slang/slang-ir-spirv-legalize.cpp index 2e9219c9d..03e823d25 100644 --- a/source/slang/slang-ir-spirv-legalize.cpp +++ b/source/slang/slang-ir-spirv-legalize.cpp @@ -41,6 +41,55 @@ struct SPIRVLegalizationContext : public SourceEmitterBase }; Dictionary<IRType*, LoweredStructuredBufferTypeInfo> m_loweredStructuredBufferTypes; + IRInst* lowerTextureFootprintType(IRInst* footprintType) + { + // Lowers `IRTextureFootprintType` to a struct with the following definition: + /* + ``` + struct __SpvTextureFootprintData<let ND : int> + { + bool isSingleLevel; + vector<uint, ND> anchor; + vector<uint, ND> offset; + uint2 mask; + uint lod; + uint granularity; + } + ``` + */ + + auto ND = footprintType->getOperand(0); + + IRBuilder builder(footprintType); + builder.setInsertBefore(footprintType); + auto structType = builder.createStructType(); + auto isSingleLevel = builder.createStructKey(); + builder.addNameHintDecoration(isSingleLevel, UnownedStringSlice("isSingleLevel")); + builder.createStructField(structType, isSingleLevel, builder.getBoolType()); + + auto anchor = builder.createStructKey(); + builder.addNameHintDecoration(anchor, UnownedStringSlice("anchor")); + builder.createStructField(structType, anchor, builder.getVectorType(builder.getUIntType(), ND)); + + auto offset = builder.createStructKey(); + builder.addNameHintDecoration(offset, UnownedStringSlice("offset")); + builder.createStructField(structType, offset, builder.getVectorType(builder.getUIntType(), ND)); + + auto mask = builder.createStructKey(); + builder.addNameHintDecoration(mask, UnownedStringSlice("mask")); + builder.createStructField(structType, mask, builder.getVectorType(builder.getUIntType(), builder.getIntValue(builder.getIntType(), 2))); + + auto lod = builder.createStructKey(); + builder.addNameHintDecoration(lod, UnownedStringSlice("lod")); + builder.createStructField(structType, lod, builder.getUIntType()); + + auto granularity = builder.createStructKey(); + builder.addNameHintDecoration(granularity, UnownedStringSlice("granularity")); + builder.createStructField(structType, granularity, builder.getUIntType()); + + return structType; + } + LoweredStructuredBufferTypeInfo lowerStructuredBufferType(IRHLSLStructuredBufferTypeBase* inst) { LoweredStructuredBufferTypeInfo result; @@ -1547,12 +1596,18 @@ struct SPIRVLegalizationContext : public SourceEmitterBase // Translate types. List<IRHLSLStructuredBufferTypeBase*> instsToProcess; + List<IRInst*> textureFootprintTypes; + for (auto globalInst : m_module->getGlobalInsts()) { if (auto t = as<IRHLSLStructuredBufferTypeBase>(globalInst)) { instsToProcess.add(t); } + else if (globalInst->getOp() == kIROp_TextureFootprintType) + { + textureFootprintTypes.add(globalInst); + } } for (auto t : instsToProcess) { @@ -1561,6 +1616,13 @@ struct SPIRVLegalizationContext : public SourceEmitterBase builder.setInsertBefore(t); t->replaceUsesWith(builder.getPtrType(kIROp_PtrType, lowered.structType, SpvStorageClassStorageBuffer)); } + for (auto t : textureFootprintTypes) + { + auto lowered = lowerTextureFootprintType(t); + IRBuilder builder(t); + builder.setInsertBefore(t); + t->replaceUsesWith(lowered); + } List<IRUse*> globalInstUsesToInline; diff --git a/source/slang/slang-lower-to-ir.cpp b/source/slang/slang-lower-to-ir.cpp index 206a47018..9686c4735 100644 --- a/source/slang/slang-lower-to-ir.cpp +++ b/source/slang/slang-lower-to-ir.cpp @@ -4561,7 +4561,9 @@ struct ExprLoweringVisitorBase : public ExprVisitor<Derived, LoweredValInfo> { if( auto declaredSubtypeWitness = as<DeclaredSubtypeWitness>(subTypeWitness) ) { - return extractField(superType, value, declaredSubtypeWitness->getDeclRef()); + // Drop the specialization info on inheritance decl struct keys, as it makes no + // sense to specialize a key. + return extractField(superType, value, declaredSubtypeWitness->getDeclRef().getDecl()); } else { diff --git a/source/slang/slang-parser.cpp b/source/slang/slang-parser.cpp index 10002ad97..821e7c813 100644 --- a/source/slang/slang-parser.cpp +++ b/source/slang/slang-parser.cpp @@ -4394,6 +4394,8 @@ namespace Slang Token closingBraceToken; while (!AdvanceIfMatch(parser, MatchedTokenType::CurlyBraces, &closingBraceToken)) { + ScopeDecl* scopeDecl = parser->astBuilder->create<ScopeDecl>(); + parser->pushScopeAndSetParent(scopeDecl); List<Token> caseNames; for (;;) { @@ -4469,6 +4471,7 @@ namespace Slang } recover:; TryRecover(parser); + parser->PopScope(); } return stmt; } diff --git a/tests/gpu-feature/texture/query/footprint/nv-shader-texture-footprint-simple.slang b/tests/gpu-feature/texture/query/footprint/nv-shader-texture-footprint-simple.slang index 782c7e7e5..e25cd4208 100644 --- a/tests/gpu-feature/texture/query/footprint/nv-shader-texture-footprint-simple.slang +++ b/tests/gpu-feature/texture/query/footprint/nv-shader-texture-footprint-simple.slang @@ -1,4 +1,5 @@ -//DISABLED_TEST:SIMPLE(filecheck=SPIRV):-target spirv-assembly -entry fragmentMain -stage fragment +//TEST:SIMPLE(filecheck=SPIRV):-target spirv-assembly -entry fragmentMain -stage fragment +//DISABLED_TEST:SIMPLE(filecheck=SPIRV):-target spirv-assembly -entry fragmentMain -stage fragment -DENABLE_CLAMP -emit-spirv-directly //DISABLED_TEST:SIMPLE(filecheck=DXIL):-target dxil-assembly -entry fragmentMain -stage fragment //TEST:SIMPLE(filecheck=HLSL):-target hlsl -entry fragmentMain -stage fragment diff --git a/tests/gpu-feature/texture/query/footprint/nv-shader-texture-footprint.slang b/tests/gpu-feature/texture/query/footprint/nv-shader-texture-footprint.slang index d5e406615..d24b14b57 100644 --- a/tests/gpu-feature/texture/query/footprint/nv-shader-texture-footprint.slang +++ b/tests/gpu-feature/texture/query/footprint/nv-shader-texture-footprint.slang @@ -1,4 +1,6 @@ -//DISABLED_TEST:SIMPLE(filecheck=SPIRV):-target spirv-assembly -entry fragmentMain -stage fragment -DENABLE_CLAMP +//TEST:SIMPLE(filecheck=SPIRV):-target spirv-assembly -entry fragmentMain -stage fragment -DENABLE_CLAMP +//DISABLED_TEST:SIMPLE(filecheck=SPIRV):-target spirv-assembly -entry fragmentMain -stage fragment -DENABLE_CLAMP -emit-spirv-directly + //DISABLED_TEST:SIMPLE(filecheck=DXIL):-target dxil-assembly -entry fragmentMain -stage fragment //TEST:SIMPLE(filecheck=HLSL):-target hlsl -entry fragmentMain -stage fragment |
