OpenGL tessellation bug

OpenGL tessellation bug

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[i]==0){
            if(M[i]<0)return false;
        }else{
            if(NM[i]>0)Left=max(Left,-M[i]/NM[i]);
            else Right=min(Right,-M[i]/NM[i]);
        }
                                                
        if(PO[i]==0){
            if(O[i]<0)return false;
        }else{
            if(PO[i]>0)Left=max(Left,-O[i]/PO[i]);
            else Right=min(Right,-O[i]/PO[i]);
        }
    }
    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()];
}

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

 

4 posts / 0 nouveau(x)
Dernière contribution
Reportez-vous à notre Notice d'optimisation pour plus d'informations sur les choix et l'optimisation des performances dans les produits logiciels Intel.

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

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.

"There is no reality in the absence of observation." - The Copenhagen Interpretation of Quantum Mechanics

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

"There is no reality in the absence of observation." - The Copenhagen Interpretation of Quantum Mechanics

Laisser un commentaire

Veuillez ouvrir une session pour ajouter un commentaire. Pas encore membre ? Rejoignez-nous dès aujourd’hui