View Single Post
Old 02-01-06, 12:22 AM   #1
undo
Registered User
 
undo's Avatar
 
Join Date: Sep 2004
Location: Dortmund, Germany
Posts: 3
Send a message via ICQ to undo Send a message via MSN to undo Send a message via Skype™ to undo
Default Serious bug in 8178 driver

Hi everybody

I found a serious bug in the 8178 driver that makes it impossible to use my GPU for many general purporse calculations under FreeBSD .

What I need to do is to create a framebuffer object (via the "EXT_framebuffer_object" extension, supported by the current driver) and attach a texture of unclamped floating point numbers to it (available via the "NV_float_buffer", "ATI_texture_float" and "ARB_texture_float" extensions, all three of which are supported by the driver).

Unfortunately, every available type of unclamped floating point texture, when attached to a FBO, leads to an error. I have written a little program that, when run, tries all the combinations I can think of and reports whether the driver accepted them or not:

Code:
#include <stdio.h>
#include <GL/glew.h>
#include <GL/glut.h>

bool openGLStatus() {
  printf("        GL Status: ");

  GLenum status = (GLenum)glGetError();
  switch(status) {
    case GL_NO_ERROR:
      printf("OK\n");
      return true;
    case GL_INVALID_ENUM:
      printf("GL_INVALID_ENUM\n");
      break;
    case GL_INVALID_VALUE:
      printf("GL_INVALID_VALUE\n");
      break;
    case GL_INVALID_OPERATION:
      printf("GL_INVALID_OPERATION\n");
      break;
    case GL_STACK_OVERFLOW:
      printf("GL_STACK_OVERFLOW\n");
      break;
    case GL_STACK_UNDERFLOW:
      printf("GL_STACK_UNDERFLOW\n");
      break;
    case GL_OUT_OF_MEMORY:
      printf("GL_OUT_OF_MEMORY\n");
      break;
    case GL_INVALID_FRAMEBUFFER_OPERATION_EXT:
      printf("GL_INVALID_FRAMEBUFFER_OPERATION_EXT\n");
      break;
    default:
      printf("UNKNWON\n");
  }

  return false;
}

void framebufferStatus() {
  printf("        FB Status: ");

  GLenum status = (GLenum)glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
  switch(status) {
    case GL_FRAMEBUFFER_COMPLETE_EXT:
      printf("<<<< OK >>>>\n");
      break;
    case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
      printf("GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT\n");
      break;
    case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
      printf("GL_FRAMEBUFFER_UNSUPPORTED_EXT\n");
      break;
    case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
      printf("GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT\n");
      break;
    case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
      printf("GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT\n");
      break;
    case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
      printf("GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT\n");
      break;
    case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
      printf("GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT\n");
      break;
    case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
      printf("GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT\n");
      break;
    default:
      printf("UNKNWON\n");
  }
}

void checkComponents(GLenum target, GLint wrap, GLenum format, GLint components) {
  // Allocate and bind an OpenGL texture
  GLuint texture;
  glGenTextures(1, &texture);
  glBindTexture(target, texture);

  // Set interpolation function to nearest-neighbor
  glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

  // Set desired wrapping type
  glTexParameteri(target, GL_TEXTURE_WRAP_S, wrap);
  glTexParameteri(target, GL_TEXTURE_WRAP_T, wrap);

  // Set texture format and component count
  glTexImage2D(target, 0, components, 16, 16, 0, format, GL_FLOAT, 0);

  // Check and show the OpenGL status; if no errors occured so far...
  if (openGLStatus()) {
    // Allocate and bind a framebuffer object
    GLuint framebuffer;
    glGenFramebuffersEXT(1, &framebuffer);
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebuffer);

    // Attempt to attach the texture to the framebuffer object
    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, target, texture, 0);

    // Check and show the framebuffer status
    framebufferStatus();

    // Detach the texture from the framebuffer object
    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, 0, 0, 0);

    // Free the framebuffer object
    glDeleteFramebuffersEXT(1, &framebuffer);
  }

  // Free the OpenGL texture
  glDeleteTextures(1, &texture);
}

void checkFormat(GLenum target, GLint wrap, GLenum format) {
  printf("      Components: GL_FLOAT_R32_NV\n");
  checkComponents(target, wrap, format, GL_FLOAT_R32_NV);
  printf("      Components: GL_LUMINANCE_FLOAT32_ATI\n");
  checkComponents(target, wrap, format, GL_LUMINANCE_FLOAT32_ATI);
  printf("      Components: GL_LUMINANCE32F_ARB\n");
  checkComponents(target, wrap, format, GL_LUMINANCE32F_ARB);
}

void checkFormat(GLenum target, GLint wrap) {
  printf("      Components: GL_FLOAT_RGBA32_NV\n");
  checkComponents(target, wrap, GL_RGBA, GL_FLOAT_RGBA32_NV);
  printf("      Components: GL_RGBA_FLOAT32_ATI\n");
  checkComponents(target, wrap, GL_RGBA, GL_RGBA_FLOAT32_ATI);
  printf("      Components: GL_RGBA32F_ARB\n");
  checkComponents(target, wrap, GL_RGBA, GL_RGBA32F_ARB);
  printf("      Components: GL_RGBA\n");
  checkComponents(target, wrap, GL_RGBA, GL_RGBA);
}

void checkWrap(GLenum target, GLint wrap) {
  printf("    Format: GL_LUMINANCE\n");
  checkFormat(target, wrap, GL_LUMINANCE);
  printf("    Format: GL_RED\n");
  checkFormat(target, wrap, GL_RED);
  printf("    Format: GL_RGBA\n");
  checkFormat(target, wrap);
}

void checkTarget(GLenum target) {
  printf("  Wrap: GL_CLAMP\n");
  checkWrap(target, GL_CLAMP);
  printf("  Wrap: GL_CLAMP_TO_EDGE\n");
  checkWrap(target, GL_CLAMP_TO_EDGE);
}

int main(int argumentCount, char **arguments) {
  glutInit (&argumentCount, arguments);
  glutCreateWindow("");
  glewInit();

  // Clear OpenGL errors
  glGetError();

  printf("Target: GL_TEXTURE_RECTANGLE_NV\n");
  checkTarget(GL_TEXTURE_RECTANGLE_NV);
  printf("Target: GL_TEXTURE_RECTANGLE_ARB\n");
  checkTarget(GL_TEXTURE_RECTANGLE_ARB);
  printf("Target: GL_TEXTURE_2D\n");
  checkTarget(GL_TEXTURE_2D);

  return 0;
}
It can be compiled (on FreeBSD) using:

Code:
g++ -I/usr/X11R6/include -L/usr/X11R6/include -lGLEW -lglut -o fbo_test fbo_test.cc
On my i386 system running 6-STABLE and equipped with a 6600 GT card, the program's output is:

Code:
Target: GL_TEXTURE_RECTANGLE_NV
  Wrap: GL_CLAMP
    Format: GL_LUMINANCE
      Components: GL_FLOAT_R32_NV
        GL Status: OK
        FB Status: GL_FRAMEBUFFER_UNSUPPORTED_EXT
      Components: GL_LUMINANCE_FLOAT32_ATI
        GL Status: GL_INVALID_ENUM
      Components: GL_LUMINANCE32F_ARB
        GL Status: OK
        FB Status: GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT
    Format: GL_RED
      Components: GL_FLOAT_R32_NV
        GL Status: GL_INVALID_ENUM
      Components: GL_LUMINANCE_FLOAT32_ATI
        GL Status: OK
        FB Status: GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT
      Components: GL_LUMINANCE32F_ARB
        GL Status: GL_INVALID_ENUM
    Format: GL_RGBA
      Components: GL_FLOAT_RGBA32_NV
        GL Status: OK
        FB Status: GL_FRAMEBUFFER_UNSUPPORTED_EXT
      Components: GL_RGBA_FLOAT32_ATI
        GL Status: GL_INVALID_ENUM
      Components: GL_RGBA32F_ARB
        GL Status: OK
        FB Status: GL_FRAMEBUFFER_UNSUPPORTED_EXT
      Components: GL_RGBA
        GL Status: GL_INVALID_ENUM
  Wrap: GL_CLAMP_TO_EDGE
    Format: GL_LUMINANCE
      Components: GL_FLOAT_R32_NV
        GL Status: OK
        FB Status: GL_FRAMEBUFFER_UNSUPPORTED_EXT
      Components: GL_LUMINANCE_FLOAT32_ATI
        GL Status: GL_INVALID_ENUM
      Components: GL_LUMINANCE32F_ARB
        GL Status: OK
        FB Status: GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT
    Format: GL_RED
      Components: GL_FLOAT_R32_NV
        GL Status: GL_INVALID_ENUM
      Components: GL_LUMINANCE_FLOAT32_ATI
        GL Status: OK
        FB Status: GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT
      Components: GL_LUMINANCE32F_ARB
        GL Status: GL_INVALID_ENUM
    Format: GL_RGBA
      Components: GL_FLOAT_RGBA32_NV
        GL Status: OK
        FB Status: GL_FRAMEBUFFER_UNSUPPORTED_EXT
      Components: GL_RGBA_FLOAT32_ATI
        GL Status: GL_INVALID_ENUM
      Components: GL_RGBA32F_ARB
        GL Status: OK
        FB Status: GL_FRAMEBUFFER_UNSUPPORTED_EXT
      Components: GL_RGBA
        GL Status: GL_INVALID_ENUM
Target: GL_TEXTURE_RECTANGLE_ARB
  Wrap: GL_CLAMP
    Format: GL_LUMINANCE
      Components: GL_FLOAT_R32_NV
        GL Status: OK
        FB Status: GL_FRAMEBUFFER_UNSUPPORTED_EXT
      Components: GL_LUMINANCE_FLOAT32_ATI
        GL Status: GL_INVALID_ENUM
      Components: GL_LUMINANCE32F_ARB
        GL Status: OK
        FB Status: GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT
    Format: GL_RED
      Components: GL_FLOAT_R32_NV
        GL Status: GL_INVALID_ENUM
      Components: GL_LUMINANCE_FLOAT32_ATI
        GL Status: OK
        FB Status: GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT
      Components: GL_LUMINANCE32F_ARB
        GL Status: GL_INVALID_ENUM
    Format: GL_RGBA
      Components: GL_FLOAT_RGBA32_NV
        GL Status: OK
        FB Status: GL_FRAMEBUFFER_UNSUPPORTED_EXT
      Components: GL_RGBA_FLOAT32_ATI
        GL Status: GL_INVALID_ENUM
      Components: GL_RGBA32F_ARB
        GL Status: OK
        FB Status: GL_FRAMEBUFFER_UNSUPPORTED_EXT
      Components: GL_RGBA
        GL Status: GL_INVALID_ENUM
  Wrap: GL_CLAMP_TO_EDGE
    Format: GL_LUMINANCE
      Components: GL_FLOAT_R32_NV
        GL Status: OK
        FB Status: GL_FRAMEBUFFER_UNSUPPORTED_EXT
      Components: GL_LUMINANCE_FLOAT32_ATI
        GL Status: GL_INVALID_ENUM
      Components: GL_LUMINANCE32F_ARB
        GL Status: OK
        FB Status: GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT
    Format: GL_RED
      Components: GL_FLOAT_R32_NV
        GL Status: GL_INVALID_ENUM
      Components: GL_LUMINANCE_FLOAT32_ATI
        GL Status: OK
        FB Status: GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT
      Components: GL_LUMINANCE32F_ARB
        GL Status: GL_INVALID_ENUM
    Format: GL_RGBA
      Components: GL_FLOAT_RGBA32_NV
        GL Status: OK
        FB Status: GL_FRAMEBUFFER_UNSUPPORTED_EXT
      Components: GL_RGBA_FLOAT32_ATI
        GL Status: GL_INVALID_ENUM
      Components: GL_RGBA32F_ARB
        GL Status: OK
        FB Status: GL_FRAMEBUFFER_UNSUPPORTED_EXT
      Components: GL_RGBA
        GL Status: GL_INVALID_ENUM
Target: GL_TEXTURE_2D
  Wrap: GL_CLAMP
    Format: GL_LUMINANCE
      Components: GL_FLOAT_R32_NV
        GL Status: GL_INVALID_OPERATION
      Components: GL_LUMINANCE_FLOAT32_ATI
        GL Status: OK
        FB Status: GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT
      Components: GL_LUMINANCE32F_ARB
        GL Status: GL_INVALID_ENUM
    Format: GL_RED
      Components: GL_FLOAT_R32_NV
        GL Status: GL_INVALID_OPERATION
      Components: GL_LUMINANCE_FLOAT32_ATI
        GL Status: OK
        FB Status: GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT
      Components: GL_LUMINANCE32F_ARB
        GL Status: GL_INVALID_ENUM
    Format: GL_RGBA
      Components: GL_FLOAT_RGBA32_NV
        GL Status: GL_INVALID_OPERATION
      Components: GL_RGBA_FLOAT32_ATI
        GL Status: OK
        FB Status: GL_FRAMEBUFFER_UNSUPPORTED_EXT
      Components: GL_RGBA32F_ARB
        GL Status: GL_INVALID_ENUM
      Components: GL_RGBA
        GL Status: OK
        FB Status: <<<< OK >>>>
  Wrap: GL_CLAMP_TO_EDGE
    Format: GL_LUMINANCE
      Components: GL_FLOAT_R32_NV
        GL Status: GL_INVALID_ENUM
      Components: GL_LUMINANCE_FLOAT32_ATI
        GL Status: OK
        FB Status: GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT
      Components: GL_LUMINANCE32F_ARB
        GL Status: GL_INVALID_ENUM
    Format: GL_RED
      Components: GL_FLOAT_R32_NV
        GL Status: GL_INVALID_OPERATION
      Components: GL_LUMINANCE_FLOAT32_ATI
        GL Status: OK
        FB Status: GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT
      Components: GL_LUMINANCE32F_ARB
        GL Status: GL_INVALID_ENUM
    Format: GL_RGBA
      Components: GL_FLOAT_RGBA32_NV
        GL Status: GL_INVALID_OPERATION
      Components: GL_RGBA_FLOAT32_ATI
        GL Status: OK
        FB Status: GL_FRAMEBUFFER_UNSUPPORTED_EXT
      Components: GL_RGBA32F_ARB
        GL Status: GL_INVALID_ENUM
      Components: GL_RGBA
        GL Status: OK
        FB Status: <<<< OK >>>>
As you see, the only case in which the attach results in "<<<< OK >>>>" is when I use a texture with internal format GL_RGBA. However, this is not an unclamped floating point type.

On the *same* machine, under Kubuntu GNU/Linux and using the 8178 driver as well, I get many combinations that work. So clearly, this is a bug in the FreeBSD driver. It is a *serious* bug because many GPGPU algorithms depend on multipass rendering into floating point textures. I myself need this for my thesis and am forced to switch to Linux until this is fixed .

The only other version of the driver available directly from ports is 7174 - but this version is so old that it does not support the "EXT_framebuffer_object", so it is of no use in this case.
undo is offline   Reply With Quote