4

Recently I updated ATI drivers (Iam using HD7970) to the newest one and some of my OpenGL project's objetcs 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 debbuger 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);
}
Kedriik
  • 331
  • 4
  • 12
  • Not an answer, but [RenderDoc](https://renderdoc.org/) might help you debug this. –  Sep 11 '17 at 17:22
  • [APITrace](https://github.com/apitrace/apitrace) is a nice tool that may help you track down the problem by comparing a capture of the rendering with NVidia vs ATI. – Jesper Juhl Sep 11 '17 at 17:58
  • If you reduce the size of the VBO, does it work? – Ripi2 Sep 11 '17 at 18:27
  • reducing VBO size still doesnt help. @Jesper Juhl now i just messing around with render doc, will try later your suggestion – Kedriik Sep 11 '17 at 19:43
  • i've done some debugging and i found that is probably something with imageStore / imageLoad in compute shaders because when i want to load from image2D something it is always vec4(0,0,0,0). Do you guys see any problem with my images2D +compute shaders? – Kedriik Sep 11 '17 at 22:26
  • @Kedriik have you check for memory leaks on CPU code side? My experience is that ATI drivers are sometimes susceptible to such things and behaves strangely if present (like not rendering VBO/VAO at all or missing faces etc). Also worth a try would be to compare release notes of old and actual ATI driver may be you see something that will hit you. You mentioned planets may be this might interests you [Is it possible to make realistic n-body solar system simulation in matter of size and mass?](https://stackoverflow.com/a/28020934/2521214) – Spektre Sep 12 '17 at 07:15
  • @Spektre Thanks will try to search for CPU memory leaks. My Planets have radius 2units and some lod, they are not extremely big i dont think this is a case but thank you for threaad. I was searching yesterday and only found that i cant load or write to image2D in compute shaders (when i retrevie random VBO position i always get zeros so it looks like every vertex is in 0,0,0 position. I dont know but maybe something is wrong with compute shaders and ATI ? – Kedriik Sep 12 '17 at 10:12
  • The code referred to in your own answer is not in the question. – Andreas Sep 13 '17 at 20:18

1 Answers1

1

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.

Kedriik
  • 331
  • 4
  • 12
  • Ah I recognize this. Some drivers default to using mipmaps so without GenerateMipmaps after texture load or Nearest filtering textures wont work. Would you mind testing GenerateMipmaps and see if you can omit the filtering fix? – Andreas Sep 13 '17 at 20:17
  • 1
    glGenerateMipmap() made my texture storage work also – Kedriik Sep 14 '17 at 17:11