OpenGL render difference between nVidia and ATI

761 views Asked by At

Recently I updated ATI drivers (I am using a HD7970) to the newest one and some of my OpenGL project's objects stopped working. What is more they work on nVidia newest drivers (tested on 960m). Is there any difference between ATI and nVidia rendering pipeline that I should know?

Additional info:

  • No error from glGetError(),
  • Shaders compiled and linked properly,
  • Other render objects works fine but VBO populating and drawing commands are different. Working one are loaded from *.obj file and draw by glDrawArrays(). Broken one's VBO is populated by polygonizator (compute shader) which takes vertices from image2D used for storage and draw by glDrawElements(),
  • with my simplest possible GPU debugger I checked that vertex and fragment shader is launching.

When I try to draw with triangles I see nothing, but when I switch to GL_POINTS I see green dots (output from fragment shader is pure green channel) which are moving as they should. This could indicate that vertex shader is lauching because MVP multipling is occurring. These are planetary LOD objects with one big VBO so I use one function to bind all buffers and other to draw necessary heightmaps. VBO size is 128MB

Initialization:

glGenBuffers(1, &VBO);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, VBO);
glBufferData(GL_SHADER_STORAGE_BUFFER, size * sizeof(vec4), NULL, GL_DYNAMIC_COPY);

glGenBuffers(1, &IndexBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexSize * sizeof(unsigned int), NULL, GL_DYNAMIC_DRAW);

glGenBuffers(1, &Normals);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, Normals);
glBufferData(GL_SHADER_STORAGE_BUFFER, size * sizeof(vec4), NULL, GL_DYNAMIC_COPY);

Populating VBO by polygonizator (compute shader):

    #version 430 core
layout( std430, binding=1 ) buffer ParamsBuffer
  {
    float size;
        uint index;
        int parentIndex;
        uint textureSize;
        vec4 upVector;
        vec4 Position;
        vec4 quadrant;
  };
  layout( std430, binding=2 ) buffer VertBuffer
  {
    vec4 VBO[ ]; 
  };

  layout( std430, binding=3 ) buffer NormalsBuffer
  {
    vec4 Normals[ ]; 
  };

 layout(std430, binding = 4) buffer IndexBuffer
{
 uint Index[];
};
  
  layout( std430, binding=10 ) buffer DebugBuffer
    {
      vec4 debug; 
    };
  layout (rgba32f)  uniform image2D HeightMap;
  layout (rgba32f)  uniform image2D NormalMap;
  layout( local_size_x = 1, local_size_y = 1, local_size_z = 1) in;

  void main(void)
  {
    uint  WGidY=(gl_WorkGroupID.y);
    uint  WGidX=(gl_WorkGroupID.x);
    uint mapVBOOffset=index*textureSize*textureSize;
    uint indexOffset=6*index*textureSize*textureSize;
        VBO[WGidY*textureSize+WGidX+mapVBOOffset]=imageLoad(HeightMap, ivec2(WGidX, WGidY));
    Normals[WGidY*textureSize+WGidX+mapVBOOffset]=imageLoad(NormalMap, ivec2(WGidX, WGidY));
   // debug=VBO[0];
    if(WGidX==textureSize-1 || WGidY==textureSize-1)
    return;
   
    uint localIndex = 6*(WGidY*textureSize+WGidX)+indexOffset;
    Index[localIndex+0]=(WGidY+1)*textureSize+WGidX  +mapVBOOffset;
    Index[localIndex+1]=WGidY*textureSize    +WGidX+1+mapVBOOffset;
    Index[localIndex+2]=WGidY*textureSize    +WGidX  +mapVBOOffset;
    Index[localIndex+3]=WGidY*textureSize    +WGidX+1+mapVBOOffset;
    Index[localIndex+4]=(WGidY+1)*textureSize+WGidX  +mapVBOOffset;
    Index[localIndex+5]=(WGidY+1)*textureSize+WGidX+1+mapVBOOffset;
    
  }

Binding:

    glUseProgram(RenderProgram);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, PerFrameBuffer);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 5, ConstantBuffer);

glEnableVertexAttribArray(2);
glBindBuffer(GL_ARRAY_BUFFER, Normals);
glVertexAttribPointer(
    2,                  
    4,                  
    GL_FLOAT,           
    GL_FALSE,           
    0,                  
    (void*)0            
);


glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glVertexAttribPointer(
    0,                  
    4,                  
    GL_FLOAT,           
    GL_FALSE,           
    0,                 
    (void*)0            
);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexBuffer);

Drawing:

float discardFactor = 0;
GLint drawMode;
if(renderMode==0)
 drawMode = GL_TRIANGLES;
if (renderMode == 1)
{
    drawMode = GL_PATCHES;
    GLint vert= 3;
    glPatchParameteri(GL_PATCH_VERTICES, 3);
}
if (tile->quadrant_x == nullptr)
{
        HeightMap hp = tile->quadrantX;
        if (CornersInFrustum(hp.Corners))
        {
            int mapOffset = tile->quadrantX.index * 6 * heightMapSize*heightMapSize * sizeof(unsigned int);
            glDrawElements(drawMode, 6 * heightMapSize*heightMapSize, GL_UNSIGNED_INT, (void*)mapOffset);
        }
    
}

if (tile->quadrant_y == nullptr)
{
    HeightMap hp = tile->quadrantY;
    if ( CornersInFrustum(hp.Corners))
    {
        int mapOffset = tile->quadrantY.index * 6 * heightMapSize*heightMapSize * sizeof(unsigned int);
        glDrawElements(drawMode, 6 * heightMapSize*heightMapSize, GL_UNSIGNED_INT, (void*)mapOffset);
        

    }
}

if (tile->quadrant_z == nullptr)
{
    HeightMap hp = tile->quadrantZ;
    if (CornersInFrustum(hp.Corners))
    {
        int mapOffset = tile->quadrantZ.index * 6 * heightMapSize*heightMapSize * sizeof(unsigned int);
        glDrawElements(drawMode, 6 * heightMapSize*heightMapSize, GL_UNSIGNED_INT, (void*)mapOffset);
    }
    
    
}

if (tile->quadrant_w == nullptr)
{
    HeightMap hp = tile->quadrantW;
    if (CornersInFrustum(hp.Corners))
    {
        int mapOffset = tile->quadrantW.index * 6 * heightMapSize*heightMapSize * sizeof(unsigned int);
        glDrawElements(drawMode, 6 * heightMapSize*heightMapSize, GL_UNSIGNED_INT, (void*)mapOffset);
    }
    
    
}

Vertex Shader:

#version 430 //core
layout(location = 0) in vec4 vertexPosition_modelspace;
layout(location = 2) in vec4 vertexNormal_modelspace;

layout(std430, binding = 4) buffer PerFrame
{
    mat4 ViewMatrix;
    vec4 CameraPosition;
    vec4 CameraForward;
    mat4 ModelMatrix;
    float time;
    float perFrametab[3];
};

layout(std430, binding = 5) buffer Constant
{
    mat4 ProjectionMatrix;
    vec4 SeedBuffer;
    vec2 screenSize;
};
layout( std430, binding=10 ) buffer DebugBuffer
{
    vec4 debug; 
};


out vec3 Position_worldspace;
out vec3 Normal_cameraspace;
out vec3 EyeDirection_cameraspace;
out vec3 LightDirection_cameraspace;
out vec3 LightPosition_worldspace;
out vec3 NormalWorldSpace;

void main()
{
gl_Position =ProjectionMatrix*
ViewMatrix*ModelMatrix*
vec4(vertexPosition_modelspace.xyz,1);

float C = 1,
near = 0.1,
far = 10000000.0f;
gl_Position.z = (2*log2(C*gl_Position.w + 1) / log2(C*far + 1) - 1) * gl_Position.w;
Position_worldspace = (ModelMatrix*vec4(vertexPosition_modelspace.xyz,1)).xyz;
Normal_cameraspace = ( ViewMatrix *(vec4(vertexNormal_modelspace.xyz,0))).xyz; 
vec4 normalTemp=ModelMatrix*vertexNormal_modelspace;
NormalWorldSpace=normalize(normalTemp.xyz);
}
1

There are 1 answers

2
Kedriik On

Ok i found a solution. The problem was in imageStore() and imageLoad() in compute shaders. Even if i used image2D for storage purpuse i needed to add

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

after generating textures. This was the difference between ATI na nVidia.