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
493 Discussions

OpenGL tessellation bug

Joseph_K_
Beginner
752 Views

Platform: Windows 8.1 x64, MSVC 2010 x64, Intel HD4600 (4770K), driver version: 10.18.10.3496

The problem: I got shader linking error when linking a program using control and evaluation "Type mismatch: Type of gl_TessLevelInner different between shaders." If I comment out the line in ES where I read that value, whole program crashes (Access violation) when trying to bind this program via glBindProgram. Tested on several nV/AMD GPUs without any issues. However, other very simple tessellation program seems to work.

Control shader:

#version 400 compatibility

layout(vertices=1)out;

uniform vec4 LightPosition;

int GreaterVec(vec3 a,vec3 b){
  return int(dot(sign(a-b),vec3(4,2,1)));
}
int ComputeMult(vec3 A,vec3 B,vec3 C,vec4 L){
  vec3 n=cross(C-A,L.xyz-A*L.w);
  return int(sign(dot(n,B-A)));
}
bool IsEdgeVisible(in vec4 A,in vec4 B){
    vec3 M=+A.xyz+A.www;
    vec3 N=+B.xyz+B.www;
    vec3 O=-A.xyz+A.www;
    vec3 P=-B.xyz+B.www;
    vec3 NM=N-M;
    vec3 PO=P-O;
    float Left=0;
    float Right=1;
    for(int i=0;i<3;++i){
        if(NM==0){
            if(M<0)return false;
        }else{
            if(NM>0)Left=max(Left,-M/NM);
            else Right=min(Right,-M/NM);
        }
                                                
        if(PO==0){
            if(O<0)return false;
        }else{
            if(PO>0)Left=max(Left,-O/PO);
            else Right=min(Right,-O/PO);
        }
    }
    return Left<=Right;
}

bool IsFullVisible(in vec4 A,in vec4 B,in vec4 C,int Diag){
  vec3 a=A.xyz;
  vec3 b=B.xyz;
  vec3 c=C.xyz;
  if(Diag>=0){
    a[Diag]=-a[Diag];
    b[Diag]=-b[Diag];
    c[Diag]=-c[Diag];
  }
    float m=(a.x-a.y);
    float n=(b.x-b.y);
    float o=(c.x-c.y);
    float p=(a.x-a.z);
    float q=(b.x-b.z);
    float r=(c.x-c.z);
  float d=(q*o-n*r);
  float t=(m*r-p*o)/d;
  float l=-(m*q-p*n)/d;
    vec4 X=A+t*B+l*C;
  return (t>0)&&(t<1)&&(l>0)&&(l<1)&&
      all(greaterThan(X.xyz,-X.www))&&all(lessThan(X.xyz,X.www));
}

#define MATRIX gl_ModelViewProjectionMatrix
bool IsVisible(in vec4 a,in vec4 b,in vec4 c,in vec4 d,vec4 l){
    vec4 A=MATRIX*a;
    vec4 B=MATRIX*b;
    vec4 C=MATRIX*c;
    vec4 D=MATRIX*d;
    vec3 n=(MATRIX*vec4(cross(b.xyz-a.xyz,l.xyz-a.xyz*l.w),0)).xyz;
    ivec3 Corner=ivec3(1+sign(n))>>1;
  if(Corner.z==1);Corner=ivec3(1)-Corner;
    int Diag=Corner.x+(Corner.y<<1)-1;
    if(IsFullVisible(A,B-A,C-A,Diag))return true;
    if(IsEdgeVisible(A,B))return true;
    if(IsEdgeVisible(A,C))return true;
    if(IsEdgeVisible(B,D))return true;
    if(IsEdgeVisible(C,D))return true;
    return false;
}

patch out vec4 P[4];

void main(){
  int Num=int(gl_in[2].gl_Position.x);

  int Multiplicity=0;
#define PLL LightPosition
#define PA gl_in[0].gl_Position
#define PB gl_in[1].gl_Position
#define PC vec4(gl_in[0].gl_Position.xyz*PLL.w-PLL.xyz,0)
#define PD vec4(gl_in[1].gl_Position.xyz*PLL.w-PLL.xyz,0)
if(!IsVisible(PA,PB,PC,PD,PLL))
{
  gl_TessLevelOuter[1]=0;
  gl_TessLevelOuter[0]=0;
  gl_TessLevelOuter[3]=gl_TessLevelOuter[2]=0.0;
  gl_TessLevelInner[1]=gl_TessLevelInner[0]=0.0;
return;
}
  for(int i=0;i<Num;++i){
#define T0 gl_in[0].gl_Position.xyz
#define T1 gl_in[1].gl_Position.xyz
#define T2 gl_in[i+3].gl_Position.xyz
    if(GreaterVec(T0,T2)>0){//T[2] T[0] T[1]?
      Multiplicity+=ComputeMult(T2,T0,T1,LightPosition);
    }else{
      if(GreaterVec(T1,T2)>0){//T[0] T[2] T[1]?
        Multiplicity-=ComputeMult(T0,T2,T1,LightPosition);
      }else{//T[0] T[1] T[2]?
        Multiplicity+=ComputeMult(T0,T1,T2,LightPosition);
      }
    }
  }

  int AbsMultiplicity=abs(Multiplicity);
  gl_TessLevelOuter[0]=int(AbsMultiplicity>0);
  gl_TessLevelOuter[2]=1;
  gl_TessLevelOuter[1]=gl_TessLevelOuter[3]=gl_TessLevelInner[0]=2*AbsMultiplicity-1;
  gl_TessLevelInner[1]=1;

  if(Multiplicity>0){
    P[0]=vec4(gl_in[1].gl_Position.xyz,1);
    P[1]=vec4(gl_in[0].gl_Position.xyz,1);
    P[2]=vec4(gl_in[1].gl_Position.xyz*LightPosition.w-LightPosition.xyz,0);
    P[3]=vec4(gl_in[0].gl_Position.xyz*LightPosition.w-LightPosition.xyz,0);
  }
  if(Multiplicity<0)
  {
    P[0]=vec4(gl_in[0].gl_Position.xyz,1);
    P[1]=vec4(gl_in[1].gl_Position.xyz,1);
    P[2]=vec4(gl_in[0].gl_Position.xyz*LightPosition.w-LightPosition.xyz,0);
    P[3]=vec4(gl_in[1].gl_Position.xyz*LightPosition.w-LightPosition.xyz,0);
  }
}

----------------------------

Evaluation shader:

#version 400 compatibility

layout(quads,fractional_odd_spacing,cw)in;

patch in vec4 P[4];

int GetIndex(){
  int x=int(round(gl_TessCoord.x*gl_TessLevelInner[0]))*2;
  int y=int(round(gl_TessCoord.y));
  int id=x+y;
  int l=((id+2)/4)%2;
  int t=(id%2)^((id/4)%2);
  return t+l*2;
}

void main(){
  gl_Position=gl_ModelViewProjectionMatrix*P[GetIndex()];
}

---------------

 

0 Kudos
3 Replies
Joseph_K_
Beginner
752 Views

A little mistake - it crashes on glUseProgram, not bind... (btw where is post edit button?)

0 Kudos
Michael_C_Intel2
Employee
752 Views

Hi Joseph,

Thanks for bring this to our attention. I have disucssed it with our OopenGL driver development team and they will investigate the issue. When I have an update I will let you know.

0 Kudos
Michael_C_Intel2
Employee
752 Views

Hi Joseph,

A new driver has been released that has a fix for your issue.

https://downloadcenter.intel.com/Detail_Desc.aspx?DwnldID=24245&lang=eng&ProdId=3720

0 Kudos
Reply