Developing Games on Intel Graphics
If you are gaming on graphics integrated in your Intel Processor, this is the place for you! Find answers to your questions or post your issues with PC games
486 Discussions

Vulkan Tessellation: vkCreateGraphicsPipelines crashes on Intel UHD 630

Geets__Andrey
New Contributor I
1,877 Views

Hi! Windows 10 X64 dirver 30.0.101.1069, 11.11.2021

I attached full demo with source HLSL files and spir-v result: VulkanDemoTerrainTesselation

Shader from VulkanDemoTerrainTesselation:

vs.vert - Vertex shader

#define location(x) [[vk::location(x)]]
struct Output {
	float4 pos : SV_POSITION;
	location(0) float2 texCoord : TEXCOORD0;
	location(1) float3 Normal : NORMAL;
};

struct Input {
	location(0) float4 pos: SV_POSITION;
	location(8) float2 uv	: TEXCOORD0;
	location(2) float3 Normal	: NORMAL;
};

Output vsMain(in Input input) {
	Output output;
	output.pos = float4(input.pos.xyz, 1.0f);
	output.Normal = input.Normal;	
	output.texCoord = input.uv;
	return output;
}

hs.tesc - Hull shader

#define location(x) [[vk::location(x)]]
#define binding(x) [[vk::binding(x)]]
#define MAX_TF 20.0f
struct ConstantsHSOutput {
		float Edges[4]	: SV_TessFactor;
		float Inside[2] : SV_InsideTessFactor;
	};
struct Input{
		float4 pos : SV_POSITION;
		location(0) float2 uv : TEXCOORD0;
		location(1) float3 Normal : NORMAL;
};
#define MAX_TF 20.0f
binding(0) cbuffer b0: register(b0) {
	row_major float4x4 view;
	row_major float4x4 proj;
	float4 cameraPosition;
	float LodDistance;
	float tessellationFactor;
	float tessellatedEdgeSize;
	float2 viewportDim;
	uint numLods;
};
float distSq(float3 p0, float3 p1) {
	float3 d = p0 - p1;
	return dot(d, d);
}
float screenSpaceTessFactor(float4 p0, float4 p1) {
	float4 midPoint = 0.5f * (p0 + p1);
	float radius = distance(p0, p1) * 0.5f;
	float4 v0 = mul(midPoint, view);	float4 clip0 = mul(float4(v0.x - radius, 
v0.yzw), proj);
	float4 clip1 = mul(float4(v0.x + radius, v0.yzw), proj);
	clip0 /= clip0.w;
	clip1 /= clip1.w;
	clip0.xy *= viewportDim;
	clip1.xy *= viewportDim;
#ifdef D3D12
	return max(distance(clip0, clip1) / tessellatedEdgeSize * tessellationFactor, 1.0f);
#else
	return clamp(distance(clip0, clip1) / tessellatedEdgeSize * tessellationFactor, 1.0f, MAX_TF);
#endif
}
float CalculateTessFactor(float4 p0, float4 p1) {
#ifdef USE_SS_TESS_FACTOR_CALC
	return screenSpaceTessFactor(p0, p1);
#else
	float3 center = (p0 + p1).xyz * 0.5f;
	float factor = LodDistance / distSq(center, cameraPosition);
	return clamp(factor, 1.0f, numLods);
#endif
}
ConstantsHSOutput ConstantsHS(InputPatch<Input, 4> ip, uint PatchID : SV_PrimitiveID) {
	ConstantsHSOutput hsOut;
	hsOut.Edges[0] = CalculateTessFactor(ip[0].pos, ip[3].pos);
	hsOut.Edges[1] = CalculateTessFactor(ip[1].pos, ip[0].pos);
	hsOut.Edges[2] = CalculateTessFactor(ip[2].pos, ip[1].pos);
	hsOut.Edges[3] = CalculateTessFactor(ip[3].pos, ip[2].pos);
	hsOut.Inside[0] = lerp(hsOut.Edges[0], hsOut.Edges[3], 0.5f);
	hsOut.Inside[1] = lerp(hsOut.Edges[1], hsOut.Edges[2], 0.5f);
	return hsOut;
}
[domain("quad")]
[partitioning("integer")]
[outputtopology("triangle_cw")]
[outputcontrolpoints(4)]
[patchconstantfunc("ConstantsHS")]
[maxtessfactor(MAX_TF)]
Input hMain(InputPatch<Input, 4> ip, uint i : SV_OutputControlPointID, uint PatchID : SV_PrimitiveID) {
	Input output;
	output.pos = float4(ip[i].pos.xyz, 1.0f);
	output.uv = ip[i].uv;
	output.Normal = ip[i].Normal;
	return output;
}

ds.tese - Domain shader

#define location(x) [[vk::location(x)]]
#define binding(x) [[vk::binding(x)]]
#define MULTIPLE_LIGHTS 1

struct ConstantsHSOutput {
		float Edges[4]	: SV_TessFactor;
		float Inside[2] : SV_InsideTessFactor;
	};
struct Output{
		location(0) float4 pos : POSITION;
		location(1) float2 texCoord : TEXCOORD0;
		location(2) float3 Normal : NORMAL;
		location(3) float3 lightDir : TEXCOORD1;
		location(4) float4 shadowCrd : TEXCOORD2;
		location(5) float4 lightProjSpaceLokup : TEXCOORD3;
		location(6) float3 vVec : TEXCOORD4;
		location(7) float3 viewDir : TEXCOORD5;
};

binding(1) cbuffer b0 : register(b0) {
	row_major float4x4 ModelViewProjection;
	row_major float4x4 proj;
	float4 cameraPosition;
	float4 LightDir;
	row_major float4x4 MatTexture;
	row_major float4x4 ViewMatrix;
	float scaleHeight;
	float2 uvScale;
};
binding(2) Texture2D HeightMap : register(t0);
binding(2) SamplerState Sampler : register(s0);
struct Input {
	location(0) float4 pos: SV_POSITION;
	location(8) float2 uv	: TEXCOORD0;
	location(2) float3 Normal	: NORMAL;
};
float4 CalcLightProjSpaceLookup(float4 projectSpace) {	projectSpace.xy = (projectSpace.xy + float2(projectSpace.w, projectSpace.w)) * 0.5;	return projectSpace;}

Output vsMain(in Input input) {
	Output output;
	float4 Pos = float4(input.pos.xyz, 1.0f); 
	output.pos = mul(Pos, ModelViewProjection);
#ifdef MULTIPLE_LIGHTS
	output.lightProjSpaceLokup = CalcLightProjSpaceLookup(output.pos);
#ifdef NO_LIGHT_VIEW_SPACE
	output.vVec = pos.xyz;
#else
	output.vVec = mul(Pos, ViewMatrix).xyz;
	output.viewDir = cameraPosition.xyz - Pos.xyz;
#endif
#endif
	output.shadowCrd = mul(Pos, MatTexture);
	output.texCoord = input.uv;
	output.Normal = mul(input.Normal, (float3x3)ViewMatrix);
	output.lightDir = -LightDir.xyz;
    return output;
}
[domain("quad")]
Output dMain(in ConstantsHSOutput input, float2 domain : SV_DomainLocation, const OutputPatch<Input, 4> patch) {
	Output dsOutput;
	Input vsIn;
	vsIn.pos = lerp(lerp(patch[0].pos, patch[1].pos, domain.x), lerp(patch[3].pos, patch[2].pos, domain.x), domain.y);
	float2 uv = vsIn.pos.xz * uvScale;
	vsIn.pos.y = HeightMap.SampleLevel(Sampler, uv, 0.0).r * scaleHeight;
	vsIn.uv = lerp(lerp(patch[0].uv, patch[1].uv, domain.x), lerp(patch[3].uv, patch[2].uv, domain.x), domain.y);
	vsIn.Normal = lerp(lerp(patch[0].Normal, patch[1].Normal, domain.x), lerp(patch[3].Normal, patch[2].Normal, domain.x), domain.y);
	dsOutput = vsMain(vsIn);
	return dsOutput;
}

ps.frag - Pixel shader

//
#define location(x) layout(location = x)
#define binding(x) [[vk::binding(x)]]
#define SIMPLE_POINT_LIGHT
#defne MULTIPLE_LIGHTS

//
struct PSOutput {
	location(0) float4 pos : SV_POSITION;
	location(1) float2 texCoord : TEXCOORD0;
	location(2) float3 Normal : NORMAL;
	location(3) float3 lightDir : TEXCOORD1;
	location(4) float4 shadowCrd: TEXCOORD2;
#ifdef MULTIPLE_LIGHTS
	location(5) float4 lightProjSpaceLokup : TEXCOORD3;
	location(6) float3 vVec : TEXCOORD4;
	location(7) float3 viewDir : TEXCOORD5;
#endif
};

binding(3) Texture2D tex1 : register(t0);
binding(3) SamplerState samLinear1 : register(s0);

binding(4) Texture2D tex2 : register(t1);
binding(4) SamplerState samLinear2 : register(s1);

binding(5) Texture2D ShadowMap : register(t2);
binding(5) SamplerState sShadowMap : register(s2);

#ifdef MULTIPLE_LIGHTS
binding(6) Texture2D BitPlane : register(t3);
binding(6) SamplerState sBitPlane : register(s3);
#endif

struct Light {
	float4 posRange;
	float4 colorLightType;
#ifndef SIMPLE_POINT_LIGHT
	float4 directionFalloff;
	float4 lighTypeAttenuation;
	float4 ThetaPhi;
#endif
};

#ifdef MULTIPLE_LIGHTS

binding(7) cbuffer b0: register(b0) {
	Light lights[NUM_LIGHTS];
};

#define NEW_MULTI_LIGHTING

#ifdef NEW_MULTI_LIGHTING

float4 CalculateLighting(float4 Color, float3 worldPos, float3 Normal, float3 viewDir, float4 lightIndex)
{
	float3 ambient_color = float3(0.0f, 0.0f, 0.0f);
    float3 color = float3(0.0f, 0.0f, 0.0f);
    
    float3 n = normalize(Normal);
    float3 v = normalize(viewDir);
#ifndef NO_LIGHT_BUFFER
    for (int i = 0; i < 4; ++i)
    {                   
		float lIndex = 256.0f * lightIndex[i];
		Light light = lights[int(lIndex)]; 
#else
    for (int i = 0; i < 255; ++i)
    {        		
		Light light = lights[i]; 
#endif
        float3 l = (light.posRange.xyz - worldPos) * light.posRange.w;
        float atten = saturate(1.0f - dot(l, l));
        l = normalize(l);
        float3 h = normalize(l + v);
        
        float nDotL = saturate(dot(n, l));
        float nDotH = saturate(dot(n, h));
        float power = (nDotL == 0.0f) ? 0.0f : pow(nDotH, 16.0f);
        
        color += (light.colorLightType.xyz * nDotL * atten) + power * atten;
    }
	color += ambient_color;
	return float4(color.xyz, Color.a);
}

#else

float4 CalculateLighting(float4 color, float3 vVec, float3 Normal, float4 lightIndex)
{
	float3 ambient_color = float3(0.2f, 0.2f, 0.2f);
	float3 lighting = float3(0.0f, 0.0f, 0.0f);
	for (int i = 0; i < 4; ++i) {
		float lIndex = 255.0f * lightIndex[i];
		Light light = lights[int(lIndex)]; 
		if (!light.posRange.w) {
	    	//return float4(0.0f, 0.0f, 0.0f, 0.0f);
			//continue;
		}
	    // Get the vector from the light center to the surface
		float3 lightVec = light.posRange.xyz - vVec;
#if 1
#if 1
 		// Scale based on the light radius
		float3 lVec = lightVec * light.posRange.a;
		float atten = 1.0f - saturate(dot(lVec, lVec));
#else
		float d = length(lightVec) / light.posRange.a;
		float atten = 1.0f - saturate(d);
#endif
#else
		float d = length(lightVec) * light.posRange.a;
		const float3 ConstantAtten = float3(0.4f, 0.01f, 0.01f);
		float atten = 1.0f / (ConstantAtten.x + ConstantAtten.y * d + ConstantAtten.z * d * d);
#endif	
		lightVec = normalize(lightVec);
		float3 H = normalize(lightVec + vVec);
		float diffuse = saturate(dot(lightVec, Normal));
		float specular = pow(saturate(dot(lightVec, H)), 16.0);
		lighting += atten * (diffuse * light.colorLightType.xyz * color.xyz + color.xyz * ambient_color + light.colorLightType.xyz * specular);
	}
	//lighting = max(lighting, 0.0f);
	return float4(lighting.xyz, color.a);
	//return float4(color.xyz, color.a);
}
#endif // NEW_MULTI_LIGHTING 
#endif // MULTIPLE_LIGHTS

float4 psMain(in PSOutput In) : SV_Target {
	
	float4 color = tex1.Sample(samLinear1, In.texCoord);
	float4 color2 = tex2.Sample(samLinear2, In.texCoord);
	color *= color2;
	float4 shadowCrd = In.shadowCrd;
	float shadowColor = 0.5f;
#ifdef PCF
	float sh = PCFFilter(4.0, ShadowMap, shadowCrd, shadowColor);
#else
	shadowCrd.xyz /= shadowCrd.w;
	float shadow = ShadowMap.Sample(sShadowMap, shadowCrd.xy).r;
	float sh = shadow < shadowCrd.z - 0.001f ? shadowColor : 1.0f;
#endif
	float3 normal = normalize(In.Normal);
#ifdef MULTIPLE_LIGHTS
	float4 lightIndex = GetLightIndex(BitPlane, In.lightProjSpaceLokup);
#ifdef NEW_MULTI_LIGHTING
	float3 viewDir = normalize(In.viewDir);
	float4 Albedo = CalculateLighting(color, In.vVec, normal, viewDir, lightIndex);
#else
	float4 Albedo = CalculateLighting(color, In.vVec, normal, lightIndex);
#endif
#endif	
	float3 lightDir = normalize(In.lightDir);
	float I = saturate(dot(lightDir, normal));
	const float3 ambient = float3(0.2f, 0.2f, 0.2f);
#ifdef MULTIPLE_LIGHTS
	color.xyz += Albedo.zyz;
#endif
	color.xyz += ambient;
	color.xyz *= I;
	color.xyz *= sh;
	return color;
}

The Direct3D12 version of the same shaders shows correct result. It is working on AMD/nVidia without crashes.
Do we have Intel driver bug or DXC/glslang translation from HLSL to SPIR-V bug ?

0 Kudos
1 Solution
Geets__Andrey
New Contributor I
1,698 Views

Problem was fixed.

Need to send correct vertex attributes from Hull Shaders -> Domain Shaders -> Pixel Shaders -> Ugly OpenGL legacy!!! 

 

Anyway Intel Vulkan Driver must't be crashed

View solution in original post

0 Kudos
1 Reply
Geets__Andrey
New Contributor I
1,699 Views

Problem was fixed.

Need to send correct vertex attributes from Hull Shaders -> Domain Shaders -> Pixel Shaders -> Ugly OpenGL legacy!!! 

 

Anyway Intel Vulkan Driver must't be crashed

0 Kudos
Reply