summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--source/slang/hlsl.meta.slang583
-rw-r--r--source/slang/slang-check-stmt.cpp7
-rw-r--r--source/slang/slang-emit-glsl.cpp12
-rw-r--r--source/slang/slang-emit-hlsl.cpp5
-rw-r--r--source/slang/slang-intrinsic-expand.cpp22
-rw-r--r--source/slang/slang-ir-inst-defs.h2
-rw-r--r--source/slang/slang-ir-spirv-legalize.cpp62
-rw-r--r--source/slang/slang-lower-to-ir.cpp4
-rw-r--r--source/slang/slang-parser.cpp3
-rw-r--r--tests/gpu-feature/texture/query/footprint/nv-shader-texture-footprint-simple.slang3
-rw-r--r--tests/gpu-feature/texture/query/footprint/nv-shader-texture-footprint.slang4
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