Commit a2b79914 by LoopDawg

HLSL: Add SampleBias and SampleGrad, and associated tests

parent efb89a3d
hlsl.sample.basicarraydx10.frag hlsl.sample.array.dx10.frag
Shader version: 450 Shader version: 450
gl_FragCoord origin is upper left gl_FragCoord origin is upper left
0:? Sequence 0:? Sequence
......
hlsl.sample.basicdx10.frag hlsl.sample.basic.dx10.frag
WARNING: 0:4: 'immediate sampler state' : unimplemented WARNING: 0:4: 'immediate sampler state' : unimplemented
Shader version: 450 Shader version: 450
......
hlsl.sample.offsetdx10.frag hlsl.sample.offset.dx10.frag
Shader version: 450 Shader version: 450
gl_FragCoord origin is upper left gl_FragCoord origin is upper left
0:? Sequence 0:? Sequence
......
hlsl.sample.offsetarraydx10.frag hlsl.sample.offsetarray.dx10.frag
Shader version: 450 Shader version: 450
gl_FragCoord origin is upper left gl_FragCoord origin is upper left
0:? Sequence 0:? Sequence
......
SamplerState g_sSamp : register(s0);
Texture1DArray g_tTex1df4a : register(t1);
uniform Texture1DArray <float4> g_tTex1df4 : register(t0);
Texture1DArray <int4> g_tTex1di4;
Texture1DArray <uint4> g_tTex1du4;
Texture2DArray <float4> g_tTex2df4;
Texture2DArray <int4> g_tTex2di4;
Texture2DArray <uint4> g_tTex2du4;
TextureCubeArray <float4> g_tTexcdf4;
TextureCubeArray <int4> g_tTexcdi4;
TextureCubeArray <uint4> g_tTexcdu4;
struct PS_OUTPUT
{
float4 Color : SV_Target0;
float Depth : SV_Depth;
};
PS_OUTPUT main()
{
PS_OUTPUT psout;
float4 txval10 = g_tTex1df4 . SampleBias(g_sSamp, float2(0.1, 0.2), 0.5);
int4 txval11 = g_tTex1di4 . SampleBias(g_sSamp, float2(0.2, 0.3), 0.5);
uint4 txval12 = g_tTex1du4 . SampleBias(g_sSamp, float2(0.3, 0.4), 0.5);
float4 txval20 = g_tTex2df4 . SampleBias(g_sSamp, float3(0.1, 0.2, 0.3), 0.5);
int4 txval21 = g_tTex2di4 . SampleBias(g_sSamp, float3(0.3, 0.4, 0.5), 0.5);
uint4 txval22 = g_tTex2du4 . SampleBias(g_sSamp, float3(0.5, 0.6, 0.7), 0.5);
float4 txval40 = g_tTexcdf4 . SampleBias(g_sSamp, float4(0.1, 0.2, 0.3, 0.4), 0.5);
int4 txval41 = g_tTexcdi4 . SampleBias(g_sSamp, float4(0.4, 0.5, 0.6, 0.7), 0.5);
uint4 txval42 = g_tTexcdu4 . SampleBias(g_sSamp, float4(0.7, 0.8, 0.9, 1.0), 0.5);
psout.Color = 1.0;
psout.Depth = 1.0;
return psout;
}
SamplerState g_sSamp : register(s0);
Texture1D g_tTex1df4a : register(t1);
uniform Texture1D <float4> g_tTex1df4 : register(t0);
Texture1D <int4> g_tTex1di4;
Texture1D <uint4> g_tTex1du4;
Texture2D <float4> g_tTex2df4;
Texture2D <int4> g_tTex2di4;
Texture2D <uint4> g_tTex2du4;
Texture3D <float4> g_tTex3df4;
Texture3D <int4> g_tTex3di4;
Texture3D <uint4> g_tTex3du4;
TextureCube <float4> g_tTexcdf4;
TextureCube <int4> g_tTexcdi4;
TextureCube <uint4> g_tTexcdu4;
struct PS_OUTPUT
{
float4 Color : SV_Target0;
float Depth : SV_Depth;
};
PS_OUTPUT main()
{
PS_OUTPUT psout;
float4 txval10 = g_tTex1df4 . SampleBias(g_sSamp, 0.1, 0.5);
int4 txval11 = g_tTex1di4 . SampleBias(g_sSamp, 0.2, 0.5);
uint4 txval12 = g_tTex1du4 . SampleBias(g_sSamp, 0.3, 0.5);
float4 txval20 = g_tTex2df4 . SampleBias(g_sSamp, float2(0.1, 0.2), 0.5);
int4 txval21 = g_tTex2di4 . SampleBias(g_sSamp, float2(0.3, 0.4), 0.5);
uint4 txval22 = g_tTex2du4 . SampleBias(g_sSamp, float2(0.5, 0.6), 0.5);
float4 txval30 = g_tTex3df4 . SampleBias(g_sSamp, float3(0.1, 0.2, 0.3), 0.5);
int4 txval31 = g_tTex3di4 . SampleBias(g_sSamp, float3(0.4, 0.5, 0.6), 0.5);
uint4 txval32 = g_tTex3du4 . SampleBias(g_sSamp, float3(0.7, 0.8, 0.9), 0.5);
float4 txval40 = g_tTexcdf4 . SampleBias(g_sSamp, float3(0.1, 0.2, 0.3), 0.5);
int4 txval41 = g_tTexcdi4 . SampleBias(g_sSamp, float3(0.4, 0.5, 0.6), 0.5);
uint4 txval42 = g_tTexcdu4 . SampleBias(g_sSamp, float3(0.7, 0.8, 0.9), 0.5);
psout.Color = 1.0;
psout.Depth = 1.0;
return psout;
}
SamplerState g_sSamp : register(s0);
Texture1D g_tTex1df4a : register(t1);
uniform Texture1D <float4> g_tTex1df4 : register(t0);
Texture1D <int4> g_tTex1di4;
Texture1D <uint4> g_tTex1du4;
Texture2D <float4> g_tTex2df4;
Texture2D <int4> g_tTex2di4;
Texture2D <uint4> g_tTex2du4;
Texture3D <float4> g_tTex3df4;
Texture3D <int4> g_tTex3di4;
Texture3D <uint4> g_tTex3du4;
TextureCube <float4> g_tTexcdf4;
TextureCube <int4> g_tTexcdi4;
TextureCube <uint4> g_tTexcdu4;
struct PS_OUTPUT
{
float4 Color : SV_Target0;
float Depth : SV_Depth;
};
PS_OUTPUT main()
{
PS_OUTPUT psout;
float4 txval10 = g_tTex1df4 . SampleBias(g_sSamp, 0.1, 0.5, 1);
int4 txval11 = g_tTex1di4 . SampleBias(g_sSamp, 0.2, 0.5, 1);
uint4 txval12 = g_tTex1du4 . SampleBias(g_sSamp, 0.3, 0.5, 1);
float4 txval20 = g_tTex2df4 . SampleBias(g_sSamp, float2(0.1, 0.2), 0.5, int2(1,0));
int4 txval21 = g_tTex2di4 . SampleBias(g_sSamp, float2(0.3, 0.4), 0.5, int2(1,1));
uint4 txval22 = g_tTex2du4 . SampleBias(g_sSamp, float2(0.5, 0.6), 0.5, int2(1,-1));
float4 txval30 = g_tTex3df4 . SampleBias(g_sSamp, float3(0.1, 0.2, 0.3), 0.5, int3(1,0,1));
int4 txval31 = g_tTex3di4 . SampleBias(g_sSamp, float3(0.4, 0.5, 0.6), 0.5, int3(1,1,1));
uint4 txval32 = g_tTex3du4 . SampleBias(g_sSamp, float3(0.7, 0.8, 0.9), 0.5, int3(1,0,-1));
// There are no offset forms of cube textures, so we do not test them.
psout.Color = 1.0;
psout.Depth = 1.0;
return psout;
}
SamplerState g_sSamp : register(s0);
Texture1DArray g_tTex1df4a : register(t1);
uniform Texture1DArray <float4> g_tTex1df4 : register(t0);
Texture1DArray <int4> g_tTex1di4;
Texture1DArray <uint4> g_tTex1du4;
Texture2DArray <float4> g_tTex2df4;
Texture2DArray <int4> g_tTex2di4;
Texture2DArray <uint4> g_tTex2du4;
struct PS_OUTPUT
{
float4 Color : SV_Target0;
float Depth : SV_Depth;
};
PS_OUTPUT main()
{
PS_OUTPUT psout;
float4 txval10 = g_tTex1df4 . SampleBias(g_sSamp, float2(0.1, 0.2), 0.5, 0);
int4 txval11 = g_tTex1di4 . SampleBias(g_sSamp, float2(0.2, 0.3), 0.5, 1);
uint4 txval12 = g_tTex1du4 . SampleBias(g_sSamp, float2(0.3, 0.4), 0.5, 2);
float4 txval20 = g_tTex2df4 . SampleBias(g_sSamp, float3(0.1, 0.2, 0.3), 0.5, int2(0,0));
int4 txval21 = g_tTex2di4 . SampleBias(g_sSamp, float3(0.3, 0.4, 0.5), 0.5, int2(0,0));
uint4 txval22 = g_tTex2du4 . SampleBias(g_sSamp, float3(0.5, 0.6, 0.7), 0.5, int2(0,1));
// No offset array forms for 3D or cube
psout.Color = 1.0;
psout.Depth = 1.0;
return psout;
}
SamplerState g_sSamp : register(s0);
Texture1DArray g_tTex1df4a : register(t1);
uniform Texture1DArray <float4> g_tTex1df4 : register(t0);
Texture1DArray <int4> g_tTex1di4;
Texture1DArray <uint4> g_tTex1du4;
Texture2DArray <float4> g_tTex2df4;
Texture2DArray <int4> g_tTex2di4;
Texture2DArray <uint4> g_tTex2du4;
TextureCubeArray <float4> g_tTexcdf4;
TextureCubeArray <int4> g_tTexcdi4;
TextureCubeArray <uint4> g_tTexcdu4;
struct PS_OUTPUT
{
float4 Color : SV_Target0;
float Depth : SV_Depth;
};
PS_OUTPUT main()
{
PS_OUTPUT psout;
float4 txval10 = g_tTex1df4 . SampleGrad(g_sSamp, float2(0.1, 0.2), 1.1, 1.2);
int4 txval11 = g_tTex1di4 . SampleGrad(g_sSamp, float2(0.1, 0.2), 1.1, 1.2);
uint4 txval12 = g_tTex1du4 . SampleGrad(g_sSamp, float2(0.1, 0.2), 1.1, 1.2);
float4 txval20 = g_tTex2df4 . SampleGrad(g_sSamp, float3(0.1, 0.2, 0.3), float2(1.1, 1.2), float2(1.1, 1.2));
int4 txval21 = g_tTex2di4 . SampleGrad(g_sSamp, float3(0.1, 0.2, 0.3), float2(1.1, 1.2), float2(1.1, 1.2));
uint4 txval22 = g_tTex2du4 . SampleGrad(g_sSamp, float3(0.1, 0.2, 0.3), float2(1.1, 1.2), float2(1.1, 1.2));
float4 txval40 = g_tTexcdf4 . SampleGrad(g_sSamp, float4(0.1, 0.2, 0.3, 0.4), float3(1.1, 1.2, 1.3), float3(1.1, 1.2, 1.3));
int4 txval41 = g_tTexcdi4 . SampleGrad(g_sSamp, float4(0.1, 0.2, 0.3, 0.4), float3(1.1, 1.2, 1.3), float3(1.1, 1.2, 1.3));
uint4 txval42 = g_tTexcdu4 . SampleGrad(g_sSamp, float4(0.1, 0.2, 0.3, 0.4), float3(1.1, 1.2, 1.3), float3(1.1, 1.2, 1.3));
psout.Color = 1.0;
psout.Depth = 1.0;
return psout;
}
SamplerState g_sSamp : register(s0);
Texture1D g_tTex1df4a : register(t1);
uniform Texture1D <float4> g_tTex1df4 : register(t0);
Texture1D <int4> g_tTex1di4;
Texture1D <uint4> g_tTex1du4;
Texture2D <float4> g_tTex2df4;
Texture2D <int4> g_tTex2di4;
Texture2D <uint4> g_tTex2du4;
Texture3D <float4> g_tTex3df4;
Texture3D <int4> g_tTex3di4;
Texture3D <uint4> g_tTex3du4;
TextureCube <float4> g_tTexcdf4;
TextureCube <int4> g_tTexcdi4;
TextureCube <uint4> g_tTexcdu4;
struct PS_OUTPUT
{
float4 Color : SV_Target0;
float Depth : SV_Depth;
};
PS_OUTPUT main()
{
PS_OUTPUT psout;
float4 txval10 = g_tTex1df4 . SampleGrad(g_sSamp, 0.1, 1.1, 1.2);
int4 txval11 = g_tTex1di4 . SampleGrad(g_sSamp, 0.2, 1.1, 1.2);
uint4 txval12 = g_tTex1du4 . SampleGrad(g_sSamp, 0.3, 1.1, 1.2);
float4 txval20 = g_tTex2df4 . SampleGrad(g_sSamp, float2(0.1, 0.2), float2(1.1, 1.2), float2(1.1, 1.2));
int4 txval21 = g_tTex2di4 . SampleGrad(g_sSamp, float2(0.3, 0.4), float2(1.1, 1.2), float2(1.1, 1.2));
uint4 txval22 = g_tTex2du4 . SampleGrad(g_sSamp, float2(0.5, 0.6), float2(1.1, 1.2), float2(1.1, 1.2));
float4 txval30 = g_tTex3df4 . SampleGrad(g_sSamp, float3(0.1, 0.2, 0.3), float3(1.1, 1.2, 1.3), float3(1.1, 1.2, 1.3));
int4 txval31 = g_tTex3di4 . SampleGrad(g_sSamp, float3(0.4, 0.5, 0.6), float3(1.1, 1.2, 1.3), float3(1.1, 1.2, 1.3));
uint4 txval32 = g_tTex3du4 . SampleGrad(g_sSamp, float3(0.7, 0.8, 0.9), float3(1.1, 1.2, 1.3), float3(1.1, 1.2, 1.3));
float4 txval40 = g_tTexcdf4 . SampleGrad(g_sSamp, float3(0.1, 0.2, 0.3), float3(1.1, 1.2, 1.3), float3(1.1, 1.2, 1.3));
int4 txval41 = g_tTexcdi4 . SampleGrad(g_sSamp, float3(0.4, 0.5, 0.6), float3(1.1, 1.2, 1.3), float3(1.1, 1.2, 1.3));
uint4 txval42 = g_tTexcdu4 . SampleGrad(g_sSamp, float3(0.7, 0.8, 0.9), float3(1.1, 1.2, 1.3), float3(1.1, 1.2, 1.3));
psout.Color = 1.0;
psout.Depth = 1.0;
return psout;
}
SamplerState g_sSamp : register(s0);
Texture1D g_tTex1df4a : register(t1);
uniform Texture1D <float4> g_tTex1df4 : register(t0);
Texture1D <int4> g_tTex1di4;
Texture1D <uint4> g_tTex1du4;
Texture2D <float4> g_tTex2df4;
Texture2D <int4> g_tTex2di4;
Texture2D <uint4> g_tTex2du4;
Texture3D <float4> g_tTex3df4;
Texture3D <int4> g_tTex3di4;
Texture3D <uint4> g_tTex3du4;
TextureCube <float4> g_tTexcdf4;
TextureCube <int4> g_tTexcdi4;
TextureCube <uint4> g_tTexcdu4;
struct VS_OUTPUT
{
float4 Pos : SV_Position;
};
VS_OUTPUT main()
{
VS_OUTPUT vsout;
float4 txval10 = g_tTex1df4 . SampleGrad(g_sSamp, 0.1, 1.1, 1.2);
int4 txval11 = g_tTex1di4 . SampleGrad(g_sSamp, 0.2, 1.1, 1.2);
uint4 txval12 = g_tTex1du4 . SampleGrad(g_sSamp, 0.3, 1.1, 1.2);
float4 txval20 = g_tTex2df4 . SampleGrad(g_sSamp, float2(0.1, 0.2), float2(1.1, 1.2), float2(1.1, 1.2));
int4 txval21 = g_tTex2di4 . SampleGrad(g_sSamp, float2(0.3, 0.4), float2(1.1, 1.2), float2(1.1, 1.2));
uint4 txval22 = g_tTex2du4 . SampleGrad(g_sSamp, float2(0.5, 0.6), float2(1.1, 1.2), float2(1.1, 1.2));
float4 txval30 = g_tTex3df4 . SampleGrad(g_sSamp, float3(0.1, 0.2, 0.3), float3(1.1, 1.2, 1.3), float3(1.1, 1.2, 1.3));
int4 txval31 = g_tTex3di4 . SampleGrad(g_sSamp, float3(0.4, 0.5, 0.6), float3(1.1, 1.2, 1.3), float3(1.1, 1.2, 1.3));
uint4 txval32 = g_tTex3du4 . SampleGrad(g_sSamp, float3(0.7, 0.8, 0.9), float3(1.1, 1.2, 1.3), float3(1.1, 1.2, 1.3));
float4 txval40 = g_tTexcdf4 . SampleGrad(g_sSamp, float3(0.1, 0.2, 0.3), float3(1.1, 1.2, 1.3), float3(1.1, 1.2, 1.3));
int4 txval41 = g_tTexcdi4 . SampleGrad(g_sSamp, float3(0.4, 0.5, 0.6), float3(1.1, 1.2, 1.3), float3(1.1, 1.2, 1.3));
uint4 txval42 = g_tTexcdu4 . SampleGrad(g_sSamp, float3(0.7, 0.8, 0.9), float3(1.1, 1.2, 1.3), float3(1.1, 1.2, 1.3));
vsout.Pos = float4(0,0,0,0);
return vsout;
}
SamplerState g_sSamp : register(s0);
Texture1D g_tTex1df4a : register(t1);
uniform Texture1D <float4> g_tTex1df4 : register(t0);
Texture1D <int4> g_tTex1di4;
Texture1D <uint4> g_tTex1du4;
Texture2D <float4> g_tTex2df4;
Texture2D <int4> g_tTex2di4;
Texture2D <uint4> g_tTex2du4;
Texture3D <float4> g_tTex3df4;
Texture3D <int4> g_tTex3di4;
Texture3D <uint4> g_tTex3du4;
TextureCube <float4> g_tTexcdf4;
TextureCube <int4> g_tTexcdi4;
TextureCube <uint4> g_tTexcdu4;
struct PS_OUTPUT
{
float4 Color : SV_Target0;
float Depth : SV_Depth;
};
PS_OUTPUT main()
{
PS_OUTPUT psout;
float4 txval10 = g_tTex1df4 . SampleGrad(g_sSamp, 0.1, 1.1, 1.2, 1);
int4 txval11 = g_tTex1di4 . SampleGrad(g_sSamp, 0.2, 1.1, 1.2, 1);
uint4 txval12 = g_tTex1du4 . SampleGrad(g_sSamp, 0.3, 1.1, 1.2, 1);
float4 txval20 = g_tTex2df4 . SampleGrad(g_sSamp, float2(0.1, 0.2), float2(0.1, 0.2), float2(1.1, 1.2), int2(1,0));
int4 txval21 = g_tTex2di4 . SampleGrad(g_sSamp, float2(0.3, 0.4), float2(0.1, 0.2), float2(1.1, 1.2), int2(1,1));
uint4 txval22 = g_tTex2du4 . SampleGrad(g_sSamp, float2(0.5, 0.6), float2(0.1, 0.2), float2(1.1, 1.2), int2(1,-1));
float4 txval30 = g_tTex3df4 . SampleGrad(g_sSamp, float3(0.1, 0.2, 0.3), float3(1.1, 1.2, 1.3), float3(1.1, 1.2, 1.3), int3(1,0,1));
int4 txval31 = g_tTex3di4 . SampleGrad(g_sSamp, float3(0.4, 0.5, 0.6), float3(1.1, 1.2, 1.3), float3(1.1, 1.2, 1.3), int3(1,1,1));
uint4 txval32 = g_tTex3du4 . SampleGrad(g_sSamp, float3(0.7, 0.8, 0.9), float3(1.1, 1.2, 1.3), float3(1.1, 1.2, 1.3), int3(1,0,-1));
// There are no offset forms of cube textures, so we do not test them.
psout.Color = 1.0;
psout.Depth = 1.0;
return psout;
}
SamplerState g_sSamp : register(s0);
Texture1DArray g_tTex1df4a : register(t1);
uniform Texture1DArray <float4> g_tTex1df4 : register(t0);
Texture1DArray <int4> g_tTex1di4;
Texture1DArray <uint4> g_tTex1du4;
Texture2DArray <float4> g_tTex2df4;
Texture2DArray <int4> g_tTex2di4;
Texture2DArray <uint4> g_tTex2du4;
TextureCubeArray <float4> g_tTexcdf4;
TextureCubeArray <int4> g_tTexcdi4;
TextureCubeArray <uint4> g_tTexcdu4;
struct PS_OUTPUT
{
float4 Color : SV_Target0;
float Depth : SV_Depth;
};
PS_OUTPUT main()
{
PS_OUTPUT psout;
float4 txval10 = g_tTex1df4 . SampleGrad(g_sSamp, float2(0.1, 0.2), 1.1, 1.2, 1);
int4 txval11 = g_tTex1di4 . SampleGrad(g_sSamp, float2(0.1, 0.2), 1.1, 1.2, 1);
uint4 txval12 = g_tTex1du4 . SampleGrad(g_sSamp, float2(0.1, 0.2), 1.1, 1.2, 1);
float4 txval20 = g_tTex2df4 . SampleGrad(g_sSamp, float3(0.1, 0.2, 0.3), float2(1.1, 1.2), float2(1.1, 1.2), int2(1,0));
int4 txval21 = g_tTex2di4 . SampleGrad(g_sSamp, float3(0.1, 0.2, 0.3), float2(1.1, 1.2), float2(1.1, 1.2), int2(1,0));
uint4 txval22 = g_tTex2du4 . SampleGrad(g_sSamp, float3(0.1, 0.2, 0.3), float2(1.1, 1.2), float2(1.1, 1.2), int2(1,0));
psout.Color = 1.0;
psout.Depth = 1.0;
return psout;
}
...@@ -526,7 +526,18 @@ enum TOperator { ...@@ -526,7 +526,18 @@ enum TOperator {
EOpTextureBias, // HLSL texture bias: will be lowered to EOpTexture EOpTextureBias, // HLSL texture bias: will be lowered to EOpTexture
EOpAsDouble, // slightly different from EOpUint64BitsToDouble EOpAsDouble, // slightly different from EOpUint64BitsToDouble
EOpMethodSample, EOpMethodSample, // Texture object methods. These are translated to existing
EOpMethodSampleBias, // AST methods, and exist to represent HLSL semantics until that
EOpMethodSampleCmp, // translation is performed. See HlslParseContext::decomposeSampleMethods().
EOpMethodSampleCmpLevelZero, // ...
EOpMethodSampleGrad, // ...
EOpMethodSampleLevel, // ...
EOpMethodLoad, // ...
EOpMethodGetDimensions, // ...
EOpMethodGetSamplePosition, // ...
EOpMethodGather, // ...
EOpMethodCalculateLevelOfDetail, // ...
EOpMethodCalculateLevelOfDetailUnclamped, // ...
}; };
class TIntermTraverser; class TIntermTraverser;
......
...@@ -94,10 +94,19 @@ INSTANTIATE_TEST_CASE_P( ...@@ -94,10 +94,19 @@ INSTANTIATE_TEST_CASE_P(
{"hlsl.intrinsics.negative.comp", "ComputeShaderFunction"}, {"hlsl.intrinsics.negative.comp", "ComputeShaderFunction"},
{"hlsl.intrinsics.negative.frag", "PixelShaderFunction"}, {"hlsl.intrinsics.negative.frag", "PixelShaderFunction"},
{"hlsl.intrinsics.negative.vert", "VertexShaderFunction"}, {"hlsl.intrinsics.negative.vert", "VertexShaderFunction"},
{"hlsl.sample.basicarraydx10.frag", "main"}, {"hlsl.sample.array.dx10.frag", "main"},
{"hlsl.sample.basicdx10.frag", "main"}, {"hlsl.sample.basic.dx10.frag", "main"},
{"hlsl.sample.offsetdx10.frag", "main"}, {"hlsl.sample.offset.dx10.frag", "main"},
{"hlsl.sample.offsetarraydx10.frag", "main"}, {"hlsl.sample.offsetarray.dx10.frag", "main"},
{"hlsl.samplebias.array.dx10.frag", "main"},
{"hlsl.samplebias.basic.dx10.frag", "main"},
{"hlsl.samplebias.offset.dx10.frag", "main"},
{"hlsl.samplebias.offsetarray.dx10.frag", "main"},
{"hlsl.samplegrad.array.dx10.frag", "main"},
{"hlsl.samplegrad.basic.dx10.frag", "main"},
{"hlsl.samplegrad.basic.dx10.vert", "main"},
{"hlsl.samplegrad.offset.dx10.frag", "main"},
{"hlsl.samplegrad.offsetarray.dx10.frag", "main"},
{"hlsl.intrinsics.vert", "VertexShaderFunction"}, {"hlsl.intrinsics.vert", "VertexShaderFunction"},
{"hlsl.matType.frag", "PixelShaderFunction"}, {"hlsl.matType.frag", "PixelShaderFunction"},
{"hlsl.max.frag", "PixelShaderFunction"}, {"hlsl.max.frag", "PixelShaderFunction"},
......
...@@ -814,9 +814,28 @@ TOperator HlslParseContext::mapAtomicOp(const TSourceLoc& loc, TOperator op, boo ...@@ -814,9 +814,28 @@ TOperator HlslParseContext::mapAtomicOp(const TSourceLoc& loc, TOperator op, boo
} }
// //
// Change texture parameters to match AST & SPIR-V semantics // Create a combined sampler/texture from separate sampler and texture.
// //
void HlslParseContext::textureParameters(const TSourceLoc& loc, TIntermTyped*& node, TIntermNode* arguments) TIntermAggregate* HlslParseContext::handleSamplerTextureCombine(const TSourceLoc& loc, TIntermTyped* argTex, TIntermTyped* argSampler)
{
TIntermAggregate* txcombine = new TIntermAggregate(EOpConstructTextureSampler);
txcombine->getSequence().push_back(argTex);
txcombine->getSequence().push_back(argSampler);
TSampler samplerType = argTex->getType().getSampler();
samplerType.combined = true;
txcombine->setType(TType(samplerType, EvqTemporary));
txcombine->setLoc(loc);
return txcombine;
}
//
// Decompose DX9 and DX10 sample intrinsics & object methods into AST
//
void HlslParseContext::decomposeSampleMethods(const TSourceLoc& loc, TIntermTyped*& node, TIntermNode* arguments)
{ {
if (!node || !node->getAsOperator()) if (!node || !node->getAsOperator())
return; return;
...@@ -825,9 +844,10 @@ void HlslParseContext::textureParameters(const TSourceLoc& loc, TIntermTyped*& n ...@@ -825,9 +844,10 @@ void HlslParseContext::textureParameters(const TSourceLoc& loc, TIntermTyped*& n
const TIntermAggregate* argAggregate = arguments ? arguments->getAsAggregate() : nullptr; const TIntermAggregate* argAggregate = arguments ? arguments->getAsAggregate() : nullptr;
switch (op) { switch (op) {
// **** DX9 intrinsics: ****
case EOpTexture: case EOpTexture:
{ {
// Texture with ddx & ddy is really gradient form // Texture with ddx & ddy is really gradient form in HLSL
if (argAggregate->getSequence().size() == 4) { if (argAggregate->getSequence().size() == 4) {
node->getAsAggregate()->setOperator(EOpTextureGrad); node->getAsAggregate()->setOperator(EOpTextureGrad);
break; break;
...@@ -869,6 +889,81 @@ void HlslParseContext::textureParameters(const TSourceLoc& loc, TIntermTyped*& n ...@@ -869,6 +889,81 @@ void HlslParseContext::textureParameters(const TSourceLoc& loc, TIntermTyped*& n
break; break;
} }
// **** DX10 methods: ****
case EOpMethodSample: // fall through
case EOpMethodSampleBias: // ...
{
TIntermTyped* argTex = argAggregate->getSequence()[0]->getAsTyped();
TIntermTyped* argSamp = argAggregate->getSequence()[1]->getAsTyped();
TIntermTyped* argCoord = argAggregate->getSequence()[2]->getAsTyped();
TIntermTyped* argBias = nullptr;
TIntermTyped* argOffset = nullptr;
int nextArg = 3;
if (op == EOpMethodSampleBias) // SampleBias has a bias arg
argBias = argAggregate->getSequence()[nextArg++]->getAsTyped();
TOperator textureOp = EOpTexture;
if (argAggregate->getSequence().size() == (nextArg+1)) { // last parameter is offset form
textureOp = EOpTextureOffset;
argOffset = argAggregate->getSequence()[nextArg++]->getAsTyped();
}
TIntermAggregate* txcombine = handleSamplerTextureCombine(loc, argTex, argSamp);
TIntermAggregate* txsample = new TIntermAggregate(textureOp);
txsample->getSequence().push_back(txcombine);
txsample->getSequence().push_back(argCoord);
if (argBias != nullptr)
txsample->getSequence().push_back(argBias);
if (argOffset != nullptr)
txsample->getSequence().push_back(argOffset);
txsample->setType(node->getType());
txsample->setLoc(loc);
node = txsample;
break;
}
case EOpMethodSampleGrad: // ...
{
TIntermTyped* argTex = argAggregate->getSequence()[0]->getAsTyped();
TIntermTyped* argSamp = argAggregate->getSequence()[1]->getAsTyped();
TIntermTyped* argCoord = argAggregate->getSequence()[2]->getAsTyped();
TIntermTyped* argDDX = argAggregate->getSequence()[3]->getAsTyped();
TIntermTyped* argDDY = argAggregate->getSequence()[4]->getAsTyped();
TIntermTyped* argOffset = nullptr;
TOperator textureOp = EOpTextureGrad;
if (argAggregate->getSequence().size() == 6) { // last parameter is offset form
textureOp = EOpTextureGradOffset;
argOffset = argAggregate->getSequence()[5]->getAsTyped();
}
TIntermAggregate* txcombine = handleSamplerTextureCombine(loc, argTex, argSamp);
TIntermAggregate* txsample = new TIntermAggregate(textureOp);
txsample->getSequence().push_back(txcombine);
txsample->getSequence().push_back(argCoord);
txsample->getSequence().push_back(argDDX);
txsample->getSequence().push_back(argDDY);
if (argOffset != nullptr)
txsample->getSequence().push_back(argOffset);
txsample->setType(node->getType());
txsample->setLoc(loc);
node = txsample;
break;
}
default: default:
break; // most pass through unchanged break; // most pass through unchanged
} }
...@@ -1223,59 +1318,6 @@ void HlslParseContext::decomposeIntrinsic(const TSourceLoc& loc, TIntermTyped*& ...@@ -1223,59 +1318,6 @@ void HlslParseContext::decomposeIntrinsic(const TSourceLoc& loc, TIntermTyped*&
} }
// //
// Decompose sample methods into AST
//
void HlslParseContext::decomposeSampleMethods(const TSourceLoc& loc, TIntermTyped*& node, TIntermNode* arguments)
{
if (!node || !node->getAsOperator())
return;
const TIntermAggregate* argAggregate = arguments ? arguments->getAsAggregate() : nullptr;
const TOperator op = node->getAsOperator()->getOp();
switch (op) {
case EOpMethodSample:
{
TIntermTyped* argTex = argAggregate->getSequence()[0]->getAsTyped();
TIntermTyped* argSamp = argAggregate->getSequence()[1]->getAsTyped();
TIntermTyped* argCoord = argAggregate->getSequence()[2]->getAsTyped();
TIntermTyped* argOffset = nullptr;
TOperator textureOp = EOpTexture;
if (argAggregate->getSequence().size() == 4) { // 4th parameter is offset form
textureOp = EOpTextureOffset;
argOffset = argAggregate->getSequence()[3]->getAsTyped();
}
TIntermAggregate* txcombine = new TIntermAggregate(EOpConstructTextureSampler);
txcombine->getSequence().push_back(argTex);
txcombine->getSequence().push_back(argSamp);
TSampler samplerType = argTex->getType().getSampler();
samplerType.combined = true;
txcombine->setType(TType(samplerType, EvqTemporary));
txcombine->setLoc(loc);
TIntermAggregate* txsample = new TIntermAggregate(textureOp);
txsample->getSequence().push_back(txcombine);
txsample->getSequence().push_back(argCoord);
if (argOffset != nullptr)
txsample->getSequence().push_back(argOffset);
txsample->setType(node->getType());
txsample->setLoc(loc);
node = txsample;
break;
}
default:
break; // most pass through unchanged
}
}
//
// Handle seeing function call syntax in the grammar, which could be any of // Handle seeing function call syntax in the grammar, which could be any of
// - .length() method // - .length() method
// - constructor // - constructor
...@@ -1380,7 +1422,6 @@ TIntermTyped* HlslParseContext::handleFunctionCall(const TSourceLoc& loc, TFunct ...@@ -1380,7 +1422,6 @@ TIntermTyped* HlslParseContext::handleFunctionCall(const TSourceLoc& loc, TFunct
decomposeIntrinsic(loc, result, arguments); // HLSL->AST intrinsic decompositions decomposeIntrinsic(loc, result, arguments); // HLSL->AST intrinsic decompositions
decomposeSampleMethods(loc, result, arguments); // HLSL->AST sample method decompositions decomposeSampleMethods(loc, result, arguments); // HLSL->AST sample method decompositions
textureParameters(loc, result, arguments); // HLSL->AST texture intrinsics
} }
} }
......
...@@ -88,7 +88,6 @@ public: ...@@ -88,7 +88,6 @@ public:
TIntermTyped* handleFunctionCall(const TSourceLoc&, TFunction*, TIntermNode*); TIntermTyped* handleFunctionCall(const TSourceLoc&, TFunction*, TIntermNode*);
void decomposeIntrinsic(const TSourceLoc&, TIntermTyped*& node, TIntermNode* arguments); void decomposeIntrinsic(const TSourceLoc&, TIntermTyped*& node, TIntermNode* arguments);
void decomposeSampleMethods(const TSourceLoc&, TIntermTyped*& node, TIntermNode* arguments); void decomposeSampleMethods(const TSourceLoc&, TIntermTyped*& node, TIntermNode* arguments);
void textureParameters(const TSourceLoc&, TIntermTyped*& node, TIntermNode* arguments);
TIntermTyped* handleLengthMethod(const TSourceLoc&, TFunction*, TIntermNode*); TIntermTyped* handleLengthMethod(const TSourceLoc&, TFunction*, TIntermNode*);
void addInputArgumentConversions(const TFunction&, TIntermNode*&) const; void addInputArgumentConversions(const TFunction&, TIntermNode*&) const;
TIntermTyped* addOutputArgumentConversions(const TFunction&, TIntermAggregate&) const; TIntermTyped* addOutputArgumentConversions(const TFunction&, TIntermAggregate&) const;
...@@ -96,6 +95,8 @@ public: ...@@ -96,6 +95,8 @@ public:
TFunction* handleConstructorCall(const TSourceLoc&, const TType&); TFunction* handleConstructorCall(const TSourceLoc&, const TType&);
void handleSemantic(TType& type, const TString& semantic); void handleSemantic(TType& type, const TString& semantic);
TIntermAggregate* handleSamplerTextureCombine(const TSourceLoc& loc, TIntermTyped* argTex, TIntermTyped* argSampler);
bool parseVectorFields(const TSourceLoc&, const TString&, int vecSize, TVectorFields&); bool parseVectorFields(const TSourceLoc&, const TString&, int vecSize, TVectorFields&);
void assignError(const TSourceLoc&, const char* op, TString left, TString right); void assignError(const TSourceLoc&, const char* op, TString left, TString right);
void unaryOpError(const TSourceLoc&, const char* op, TString operand); void unaryOpError(const TSourceLoc&, const char* op, TString operand);
......
...@@ -67,23 +67,38 @@ const char* BaseTypeName(const char argOrder, const char* scalarName, const char ...@@ -67,23 +67,38 @@ const char* BaseTypeName(const char argOrder, const char* scalarName, const char
} }
} }
bool IsTextureType(const char argOrder) { return argOrder == '%' || argOrder == '@'; } bool IsTextureType(const char argOrder) { return argOrder == '%' || argOrder == '@'; }
bool IsTextureArrayed(const char argOrder) { return argOrder == '@'; } bool IsTextureArrayed(const char argOrder) { return argOrder == '@'; }
bool IsTextureMS(const char argOrder) { return false; } // TODO: ...
// Reject certain combinations that are illegal sample methods. For example, // Reject certain combinations that are illegal sample methods. For example,
// 3D arrays. // 3D arrays.
bool IsIllegalSample(const glslang::TString& name, const char* argOrder, int dim0) bool IsIllegalSample(const glslang::TString& name, const char* argOrder, int dim0)
{ {
const bool isArrayed = IsTextureArrayed(*argOrder); const bool isArrayed = IsTextureArrayed(*argOrder);
const bool isMS = IsTextureMS(*argOrder);
if (isArrayed && dim0 == 3) // there are no 3D arrayed textures. // there are no 3D arrayed textures, or 3D SampleCmp
if (dim0 == 3 && (isArrayed || name == "SampleCmp"))
return true; return true;
const int numArgs = int(std::count(argOrder, argOrder + strlen(argOrder), ',')) + 1; const int numArgs = int(std::count(argOrder, argOrder + strlen(argOrder), ',')) + 1;
// Reject invalid offset arrayed forms. // Reject invalid offset arrayed forms with cubemaps
if (isArrayed && dim0 == 4) { if (isArrayed && dim0 == 4) {
if (name == "Sample" && numArgs == 4) if ((name == "Sample" && numArgs >= 4) ||
(name == "SampleBias" && numArgs >= 5) ||
(name == "SampleCmp" && numArgs >= 5) ||
(name == "SampleCmpLevelZero" && numArgs >= 4) ||
(name == "SampleGrad" && numArgs >= 6) ||
(name == "SampleLevel" && numArgs >= 5))
return true;
}
// Reject invalid Loads
if (name == "Load") {
if ((numArgs >= 3 && !isMS) || // Load with sampleindex requires multisample
(dim0 == 4)) // Load does not support any cubemaps, arrayed or not.
return true; return true;
} }
...@@ -103,6 +118,7 @@ glslang::TString& AppendTypeName(glslang::TString& s, const char* argOrder, cons ...@@ -103,6 +118,7 @@ glslang::TString& AppendTypeName(glslang::TString& s, const char* argOrder, cons
const bool isMatMul = (argOrder[0] == '#'); const bool isMatMul = (argOrder[0] == '#');
const bool isTexture = IsTextureType(argOrder[0]); const bool isTexture = IsTextureType(argOrder[0]);
const bool isArrayed = IsTextureArrayed(argOrder[0]); const bool isArrayed = IsTextureArrayed(argOrder[0]);
const bool isMS = IsTextureMS(argOrder[0]);
char order = *argOrder; char order = *argOrder;
char type = *argType; char type = *argType;
...@@ -187,14 +203,14 @@ glslang::TString& AppendTypeName(glslang::TString& s, const char* argOrder, cons ...@@ -187,14 +203,14 @@ glslang::TString& AppendTypeName(glslang::TString& s, const char* argOrder, cons
switch (order) { switch (order) {
case '-': break; // no dimensions for voids case '-': break; // no dimensions for voids
case 'S': break; // no dimensions on scalars case 'S': break; // no dimensions on scalars
case 'V': s += ('0' + (char)dim0); break; case 'V': s += ('0' + char(dim0)); break;
case 'M': case 'M':
{ {
if (!UseHlslTypes) // GLSL has column first for mat types if (!UseHlslTypes) // GLSL has column first for mat types
std::swap(dim0, dim1); std::swap(dim0, dim1);
s += ('0' + (char)dim0); s += ('0' + char(dim0));
s += 'x'; s += 'x';
s += ('0' + (char)dim1); s += ('0' + char(dim1));
break; break;
} }
} }
...@@ -517,10 +533,43 @@ void TBuiltInParseablesHlsl::initialize(int /*version*/, EProfile /*profile*/, c ...@@ -517,10 +533,43 @@ void TBuiltInParseablesHlsl::initialize(int /*version*/, EProfile /*profile*/, c
// Texture object methods. Return type can be overridden by shader declaration. // Texture object methods. Return type can be overridden by shader declaration.
// !O = no offset, O = offset, !A = no array, A = array // !O = no offset, O = offset, !A = no array, A = array
{ "Sample", /*!O !A*/ "V4", nullptr, "%V,S,V", "FIU,S,F", EShLangFragmentMask }, { "Sample", /*!O !A*/ "V4", nullptr, "%V,S,V", "FIU,S,F", EShLangFragmentMask },
{ "Sample", /* O !A*/ "V4", nullptr, "%V,S,V,V", "FIU,S,F,I", EShLangFragmentMask }, { "Sample", /* O !A*/ "V4", nullptr, "%V,S,V,V", "FIU,S,F,I", EShLangFragmentMask },
{ "Sample", /*!O A*/ "V4", nullptr, "@V,S,V", "FIU,S,F", EShLangFragmentMask }, { "Sample", /*!O A*/ "V4", nullptr, "@V,S,V", "FIU,S,F", EShLangFragmentMask },
{ "Sample", /* O A*/ "V4", nullptr, "@V,S,V,V", "FIU,S,F,I", EShLangFragmentMask }, { "Sample", /* O A*/ "V4", nullptr, "@V,S,V,V", "FIU,S,F,I", EShLangFragmentMask },
{ "SampleBias", /*!O !A*/ "V4", nullptr, "%V,S,V,S", "FIU,S,F,F", EShLangFragmentMask },
{ "SampleBias", /* O !A*/ "V4", nullptr, "%V,S,V,S,V", "FIU,S,F,F,I", EShLangFragmentMask },
{ "SampleBias", /*!O A*/ "V4", nullptr, "@V,S,V,S", "FIU,S,F,F", EShLangFragmentMask },
{ "SampleBias", /* O A*/ "V4", nullptr, "@V,S,V,S,V", "FIU,S,F,F,I", EShLangFragmentMask },
// { "SampleCmp", /*!O !A*/ "V4", nullptr, "%V,S,V,S", "FIU,S,F,F", EShLangFragmentMask },
// { "SampleCmp", /* O !A*/ "V4", nullptr, "%V,S,V,S,V", "FIU,S,F,F,I", EShLangFragmentMask },
// { "SampleCmp", /*!O A*/ "V4", nullptr, "@V,S,V,S", "FIU,S,F,F", EShLangFragmentMask },
// { "SampleCmp", /* O A*/ "V4", nullptr, "@V,S,V,S,V", "FIU,S,F,F,I", EShLangFragmentMask },
// { "SampleCmpLevelZero", /*!O !A*/ "V4", nullptr, "%V,S,V", "FIU,S,F", EShLangFragmentMask },
// { "SampleCmpLevelZero", /* O !A*/ "V4", nullptr, "%V,S,V,V", "FIU,S,F,I", EShLangFragmentMask },
// { "SampleCmpLevelZero", /*!O A*/ "V4", nullptr, "@V,S,V", "FIU,S,F", EShLangFragmentMask },
// { "SampleCmpLevelZero", /* O A*/ "V4", nullptr, "@V,S,V,V", "FIU,S,F,I", EShLangFragmentMask },
{ "SampleGrad", /*!O !A*/ "V4", nullptr, "%V,S,V,V,V", "FIU,S,F,F,F", EShLangAll },
{ "SampleGrad", /* O !A*/ "V4", nullptr, "%V,S,V,V,V,V", "FIU,S,F,F,F,I", EShLangAll },
{ "SampleGrad", /*!O A*/ "V4", nullptr, "@V,S,V,V,V", "FIU,S,F,F,F", EShLangAll },
{ "SampleGrad", /* O A*/ "V4", nullptr, "@V,S,V,V,V,V", "FIU,S,F,F,F,I", EShLangAll },
// { "SampleLevel", /*!O !A*/ "V4", nullptr, "%V,S,V,S", "FIU,S,F,F", EShLangFragmentMask },
// { "SampleLevel", /* O !A*/ "V4", nullptr, "%V,S,V,S,V", "FIU,S,F,F,I", EShLangFragmentMask },
// { "SampleLevel", /*!O A*/ "V4", nullptr, "@V,S,V,S", "FIU,S,F,F", EShLangFragmentMask },
// { "SampleLevel", /* O A*/ "V4", nullptr, "@V,S,V,S,V", "FIU,S,F,F,I", EShLangFragmentMask },
// TODO: ...
// { "Load", "V4", nullptr, "%V,V", "FIU,I", EShLangFragmentMask },
// { "Load", /* +sampleidex*/ "V4", nullptr, "%V,V,S", "FIU,I,I", EShLangFragmentMask },
// { "Load", /* +samplindex, offset*/ "V4", nullptr, "%V,V,S,V", "FIU,I,I,I", EShLangFragmentMask },
// { "Load", "V4", nullptr, "@V,V", "FIU,I", EShLangFragmentMask },
// { "Load", /* +sampleidex*/ "V4", nullptr, "@V,V,S", "FIU,I,I", EShLangFragmentMask },
// { "Load", /* +samplindex, offset*/ "V4", nullptr, "@V,V,S,V", "FIU,I,I,I", EShLangFragmentMask },
// Mark end of list, since we want to avoid a range-based for, as some compilers don't handle it yet. // Mark end of list, since we want to avoid a range-based for, as some compilers don't handle it yet.
{ nullptr, nullptr, nullptr, nullptr, nullptr, 0 }, { nullptr, nullptr, nullptr, nullptr, nullptr, 0 },
...@@ -565,7 +614,7 @@ void TBuiltInParseablesHlsl::initialize(int /*version*/, EProfile /*profile*/, c ...@@ -565,7 +614,7 @@ void TBuiltInParseablesHlsl::initialize(int /*version*/, EProfile /*profile*/, c
continue; continue;
// Reject some forms of sample methods that don't exist. // Reject some forms of sample methods that don't exist.
if (isTexture && IsIllegalSample(s, argOrder, dim0)) if (isTexture && IsIllegalSample(intrinsic.name, argOrder, dim0))
continue; continue;
AppendTypeName(s, retOrder, retType, dim0, dim1); // add return type AppendTypeName(s, retOrder, retType, dim0, dim1); // add return type
...@@ -796,6 +845,12 @@ void TBuiltInParseablesHlsl::identifyBuiltIns(int /*version*/, EProfile /*profil ...@@ -796,6 +845,12 @@ void TBuiltInParseablesHlsl::identifyBuiltIns(int /*version*/, EProfile /*profil
// Texture methods // Texture methods
symbolTable.relateToOperator("Sample", EOpMethodSample); symbolTable.relateToOperator("Sample", EOpMethodSample);
symbolTable.relateToOperator("SampleBias", EOpMethodSampleBias);
// symbolTable.relateToOperator("SampleCmp", EOpMethodSampleCmp);
// symbolTable.relateToOperator("SampleCmpLevelZero", EOpMethodSampleCmpLevelZero);
symbolTable.relateToOperator("SampleGrad", EOpMethodSampleGrad);
// symbolTable.relateToOperator("SampleLevel", EOpMethodSampleLevel);
// symbolTable.relateToOperator("Load", EOpMethodLoad);
} }
// //
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment