Skip to content

Commit

Permalink
Add HLSL texture sample with status intrinsics (#5901)
Browse files Browse the repository at this point in the history
* Implement HLSL texture sample with status intrinsics

* fix test and cleanup

---------

Co-authored-by: Yong He <[email protected]>
  • Loading branch information
fairywreath and csyonghe authored Dec 19, 2024
1 parent c6662b6 commit 237af82
Show file tree
Hide file tree
Showing 2 changed files with 201 additions and 15 deletions.
156 changes: 155 additions & 1 deletion source/slang/hlsl.meta.slang
Original file line number Diff line number Diff line change
Expand Up @@ -1057,6 +1057,22 @@ extension _Texture<T,Shape,isArray,isMS,sampleCount,0,isShadow,1,format>
}
}

[__readNone]
[ForceInline]
[require(hlsl, sm_5_0)]
T SampleBias(vector<float, Shape.dimensions+isArray> location, float bias, constexpr vector<int, Shape.planeDimensions> offset, float clamp, out uint status)
{
__requireComputeDerivative();
__target_switch
{
case hlsl:
static_assert(T is float || T is vector<float,2> || T is vector<float,3> || T is vector<float,4>
|| T is half || T is vector<half,2> || T is vector<half,3> || T is vector<half,4>
, "HLSL supports only float and half type textures");
return __getTexture().SampleBias(__getSampler(), location, bias, offset, clamp, status);
}
}

[__readNone]
[ForceInline]
[require(glsl_hlsl_metal_spirv_wgsl, texture_shadowlod)]
Expand Down Expand Up @@ -1163,6 +1179,23 @@ extension _Texture<T,Shape,isArray,isMS,sampleCount,0,isShadow,1,format>
}
}


[__readNone]
[ForceInline]
[require(hlsl, sm_5_0)]
float SampleCmp(vector<float, Shape.dimensions+isArray> location, float compareValue, constexpr vector<int, Shape.planeDimensions> offset, float clamp, out uint status)
{
__requireComputeDerivative();
__target_switch
{
case hlsl:
static_assert(T is float || T is vector<float,2> || T is vector<float,3> || T is vector<float,4>
|| T is half || T is vector<half,2> || T is vector<half,3> || T is vector<half,4>
, "HLSL supports only float and half type textures");
return __getTexture().SampleCmp(__getComparisonSampler(), location, compareValue, offset, clamp, status);
}
}

[__readNone]
[ForceInline]
[require(glsl_hlsl_metal_spirv_wgsl, texture_shadowlod)]
Expand Down Expand Up @@ -1197,6 +1230,21 @@ extension _Texture<T,Shape,isArray,isMS,sampleCount,0,isShadow,1,format>
}
}

[__readNone]
[ForceInline]
[require(hlsl, sm_5_0)]
float SampleCmpLevelZero(vector<float, Shape.dimensions+isArray> location, float compareValue, constexpr vector<int, Shape.planeDimensions> offset, out uint status)
{
__target_switch
{
case hlsl:
static_assert(T is float || T is vector<float,2> || T is vector<float,3> || T is vector<float,4>
|| T is half || T is vector<half,2> || T is vector<half,3> || T is vector<half,4>
, "HLSL supports only float and half type textures");
return __getTexture().SampleCmpLevelZero(__getComparisonSampler(), location, compareValue, offset, status);
}
}

[__readNone]
[ForceInline]
[require(cpp_glsl_hlsl_metal_spirv_wgsl, texture_sm_4_0)]
Expand Down Expand Up @@ -1281,6 +1329,21 @@ extension _Texture<T,Shape,isArray,isMS,sampleCount,0,isShadow,1,format>
}
}

[__readNone]
[ForceInline]
[require(hlsl, sm_5_0)]
T SampleGrad(vector<float, Shape.dimensions+isArray> location, vector<float, Shape.dimensions> gradX, vector<float, Shape.dimensions> gradY, constexpr vector<int, Shape.dimensions> offset, float lodClamp, out uint status)
{
__target_switch
{
case hlsl:
static_assert(T is float || T is vector<float,2> || T is vector<float,3> || T is vector<float,4>
|| T is half || T is vector<half,2> || T is vector<half,3> || T is vector<half,4>
, "HLSL supports only float and half type textures");
return __getTexture().SampleGrad(__getSampler(), location, gradX, gradY, offset, lodClamp, status);
}
}

[__readNone]
[ForceInline]
[require(cpp_cuda_glsl_hlsl_metal_spirv_wgsl, texture_sm_4_0)]
Expand Down Expand Up @@ -1367,6 +1430,21 @@ extension _Texture<T,Shape,isArray,isMS,sampleCount,0,isShadow,1,format>
return __getTexture().SampleLevel(__getSampler(), location, level, offset);
}
}

[__readNone]
[ForceInline]
[require(hlsl, sm_5_0)]
T SampleLevel(vector<float, Shape.dimensions+isArray> location, float level, constexpr vector<int, Shape.planeDimensions> offset, out uint status)
{
__target_switch
{
case hlsl:
static_assert(T is float || T is vector<float,2> || T is vector<float,3> || T is vector<float,4>
|| T is half || T is vector<half,2> || T is vector<half,3> || T is vector<half,4>
, "HLSL supports only float and half type textures");
return __getTexture().SampleLevel(__getSampler(), location, level, offset, status);
}
}
}

// Non-combined texture types specific functions
Expand Down Expand Up @@ -1783,6 +1861,22 @@ extension _Texture<T,Shape,isArray,isMS,sampleCount,0,isShadow,0,format>
}
}

[__readNone]
[ForceInline]
[require(hlsl, sm_5_0)]
T SampleBias(SamplerState s, vector<float, Shape.dimensions+isArray> location, float bias, constexpr vector<int, Shape.planeDimensions> offset, float clamp, out uint status)
{
__requireComputeDerivative();
__target_switch
{
case hlsl:
static_assert(T is float || T is vector<float,2> || T is vector<float,3> || T is vector<float,4>
|| T is half || T is vector<half,2> || T is vector<half,3> || T is vector<half,4>
, "HLSL supports only float and half type textures");
__intrinsic_asm ".SampleBias";
}
}

[__readNone]
[ForceInline]
[require(glsl_hlsl_metal_spirv_wgsl, texture_shadowlod)]
Expand Down Expand Up @@ -1988,6 +2082,22 @@ extension _Texture<T,Shape,isArray,isMS,sampleCount,0,isShadow,0,format>
}
}

[__readNone]
[ForceInline]
[require(hlsl, sm_5_0)]
float SampleCmp(SamplerComparisonState s, vector<float, Shape.dimensions+isArray> location, float compareValue, constexpr vector<int, Shape.planeDimensions> offset, float clamp, out uint status)
{
__requireComputeDerivative();
__target_switch
{
case hlsl:
static_assert(T is float || T is vector<float,2> || T is vector<float,3> || T is vector<float,4>
|| T is half || T is vector<half,2> || T is vector<half,3> || T is vector<half,4>
, "HLSL supports only float and half type textures");
__intrinsic_asm ".SampleCmp";
}
}

[__readNone]
[ForceInline]
[require(glsl_hlsl_metal_spirv_wgsl, texture_shadowlod)]
Expand Down Expand Up @@ -2055,6 +2165,21 @@ extension _Texture<T,Shape,isArray,isMS,sampleCount,0,isShadow,0,format>
}
}

[__readNone]
[ForceInline]
[require(hlsl, sm_5_0)]
float SampleCmpLevelZero(SamplerComparisonState s, vector<float, Shape.dimensions+isArray> location, float compareValue, constexpr vector<int, Shape.planeDimensions> offset, out uint status)
{
__target_switch
{
case hlsl:
static_assert(T is float || T is vector<float,2> || T is vector<float,3> || T is vector<float,4>
|| T is half || T is vector<half,2> || T is vector<half,3> || T is vector<half,4>
, "HLSL supports only float and half type textures");
__intrinsic_asm ".SampleCmpLevelZero";
}
}

[__readNone]
[ForceInline]
[require(cpp_glsl_hlsl_metal_spirv_wgsl, texture_sm_4_0)]
Expand Down Expand Up @@ -2235,6 +2360,21 @@ extension _Texture<T,Shape,isArray,isMS,sampleCount,0,isShadow,0,format>
}
}

[__readNone]
[ForceInline]
[require(hlsl, sm_5_0)]
T SampleGrad(SamplerState s, vector<float, Shape.dimensions+isArray> location, vector<float, Shape.dimensions> gradX, vector<float, Shape.dimensions> gradY, constexpr vector<int, Shape.dimensions> offset, float lodClamp, out uint status)
{
__target_switch
{
case hlsl:
static_assert(T is float || T is vector<float,2> || T is vector<float,3> || T is vector<float,4>
|| T is half || T is vector<half,2> || T is vector<half,3> || T is vector<half,4>
, "HLSL supports only float and half type textures");
__intrinsic_asm ".SampleGrad";
}
}

[__readNone]
[ForceInline]
[require(cpp_cuda_glsl_hlsl_metal_spirv_wgsl, texture_sm_4_0)]
Expand Down Expand Up @@ -2337,7 +2477,6 @@ extension _Texture<T,Shape,isArray,isMS,sampleCount,0,isShadow,0,format>

[__readNone]
[ForceInline]

[require(cpp_glsl_hlsl_metal_spirv_wgsl, texture_sm_4_0)]
T SampleLevel(SamplerState s, vector<float, Shape.dimensions+isArray> location, float level, constexpr vector<int, Shape.planeDimensions> offset)
{
Expand Down Expand Up @@ -2399,6 +2538,21 @@ extension _Texture<T,Shape,isArray,isMS,sampleCount,0,isShadow,0,format>
__intrinsic_asm "textureSampleLevel($0, $1, $2, $3, $4)$z";
}
}

[__readNone]
[ForceInline]
[require(hlsl, sm_5_0)]
T SampleLevel(SamplerState s, vector<float, Shape.dimensions+isArray> location, float level, constexpr vector<int, Shape.planeDimensions> offset, out uint status)
{
__target_switch
{
case hlsl:
static_assert(T is float || T is vector<float,2> || T is vector<float,3> || T is vector<float,4>
|| T is half || T is vector<half,2> || T is vector<half,3> || T is vector<half,4>
, "HLSL supports only float and half type textures");
__intrinsic_asm ".SampleLevel";
}
}
}

// Texture.GetDimensions and Sampler.GetDimensions
Expand Down
60 changes: 46 additions & 14 deletions tests/hlsl-intrinsic/texture/texture-intrinsics.slang
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,14 @@ void computeMain(int3 dispatchThreadID: SV_DispatchThreadID)
uint numLevels = 0, elements = 0;
float fnumLevels = 0.0f, felements = 0.0f;

float clamp = 0.0f;
float bias = 0.0f;

uint status;

/*
<Template Type> Object.SampleLevel()
*/
*/
val += t1D.SampleLevel(samplerState, u, 0);
val += t2D.SampleLevel(samplerState, float2(u, u), 0);
val += t3D.SampleLevel(samplerState, float3(u, u, u), 0);
Expand All @@ -66,6 +69,16 @@ void computeMain(int3 dispatchThreadID: SV_DispatchThreadID)
val += t1DArray.SampleLevel(samplerState, float2(u, 0), 0, 1);
val += t2DArray.SampleLevel(samplerState, float3(u, u, 0), 0, int2(1, 1));

// Status variant
#if !defined(VK)
val += t1D.SampleLevel(samplerState, u, 0, 1, status);
val += t2D.SampleLevel(samplerState, float2(u, u), 0, int2(1, 1), status);
val += t3D.SampleLevel(samplerState, float3(u, u, u), 0, int3(1, 1, 1), status);

val += t1DArray.SampleLevel(samplerState, float2(u, 0), 0, 1, status);
val += t2DArray.SampleLevel(samplerState, float3(u, u, 0), 0, int2(1, 1), status);
#endif

/*
float Object.SampleCmpLevelZero()
*/
Expand All @@ -82,6 +95,15 @@ void computeMain(int3 dispatchThreadID: SV_DispatchThreadID)
val += t2D.SampleCmpLevelZero(shadowSampler, float2(u, u), 0, int2(0, 0));
// TextureCube does not have an offset version of this

// Status variant
#if !defined(VK)
val += t1D.SampleCmpLevelZero(shadowSampler, u, 0, 0, status);
val += t2D.SampleCmpLevelZero(shadowSampler, float2(u, u), 0, int2(0, 0), status);

val += t1DArray.SampleCmpLevelZero(shadowSampler, float2(u, u), 0, 0, status);
val += t2DArray.SampleCmpLevelZero(shadowSampler, normalize(float3(u, 1 - u, u)), 0, int2(0, 0), status);
#endif

/*
void Object.GetDimensions()
*/
Expand Down Expand Up @@ -306,22 +328,32 @@ void computeMain(int3 dispatchThreadID: SV_DispatchThreadID)
val += t1DArray.SampleGrad(samplerState, float2(0.0f, 0.0f), _ddx, _ddy, 0);
val += t2DArray.SampleGrad(samplerState, float3(u, u, 0.0f), float2(_ddx, _ddx), float2(_ddy, _ddy), int2(0, 0));

// Status variant
#if !defined(VK)
val += t1D.SampleGrad(samplerState, 0.0f, _ddx, _ddy, 0, clamp, status);
val += t2D.SampleGrad(samplerState, float2(u, u), float2(_ddx, _ddx), float2(_ddy, _ddy), int2(0, 0), clamp, status);
val += t3D.SampleGrad(samplerState, float3(u, u, u), float3(_ddx, _ddx, _ddx), float3(_ddy, _ddy, _ddy), int3(0, 0, 0), clamp, status);

val += t1DArray.SampleGrad(samplerState, float2(0.0f, 0.0f), _ddx, _ddy, 0, clamp, status);
val += t2DArray.SampleGrad(samplerState, float3(u, u, 0.0f), float2(_ddx, _ddx), float2(_ddy, _ddy), int2(0, 0), clamp, status);
#endif

outputBuffer[idx] = val;
}

// DX11: 313
// DX11: 313
// DX11: 313
// DX11: 313
// DX12: 340
// DX12: 340
// DX12: 340
// DX12: 340
// DX12CS6: 363
// DX12CS6: 363
// DX12CS6: 363
// DX12CS6: 363
// VK: 351
// DX11: 327
// DX11: 327
// DX11: 327
// DX11: 327
// DX12: 354
// DX12: 354
// DX12: 354
// DX12: 354
// DX12CS6: 377
// DX12CS6: 377
// DX12CS6: 377
// DX12CS6: 377
// VK: 351
// VK: 351
// VK: 351
// VK: 351

0 comments on commit 237af82

Please sign in to comment.