Browse Source

glsl: support passing uint variables to shader

rdb 7 years ago
parent
commit
06539f5c66

+ 1 - 0
panda/src/glstuff/glCgShaderContext_src.cxx

@@ -648,6 +648,7 @@ issue_parameters(int altered) {
         continue;
         continue;
 
 
       case Shader::SPT_int:
       case Shader::SPT_int:
+      case Shader::SPT_uint:
         switch (spec._info._class) {
         switch (spec._info._class) {
         case Shader::SAC_scalar:
         case Shader::SAC_scalar:
           cgSetParameter1iv(p, (int*)ptr_data->_ptr);
           cgSetParameter1iv(p, (int*)ptr_data->_ptr);

+ 12 - 0
panda/src/glstuff/glGraphicsStateGuardian_src.cxx

@@ -1699,6 +1699,14 @@ reset() {
        get_extension_func("glUniform3iv");
        get_extension_func("glUniform3iv");
     _glUniform4iv = (PFNGLUNIFORM4IVPROC)
     _glUniform4iv = (PFNGLUNIFORM4IVPROC)
        get_extension_func("glUniform4iv");
        get_extension_func("glUniform4iv");
+    _glUniform1uiv = (PFNGLUNIFORM1UIVPROC)
+       get_extension_func("glUniform1uiv");
+    _glUniform2uiv = (PFNGLUNIFORM2UIVPROC)
+       get_extension_func("glUniform2uiv");
+    _glUniform3uiv = (PFNGLUNIFORM3UIVPROC)
+       get_extension_func("glUniform3uiv");
+    _glUniform4uiv = (PFNGLUNIFORM4UIVPROC)
+       get_extension_func("glUniform4uiv");
     _glUniformMatrix3fv = (PFNGLUNIFORMMATRIX3FVPROC)
     _glUniformMatrix3fv = (PFNGLUNIFORMMATRIX3FVPROC)
        get_extension_func("glUniformMatrix3fv");
        get_extension_func("glUniformMatrix3fv");
     _glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC)
     _glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC)
@@ -1777,6 +1785,10 @@ reset() {
   _glUniform2fv = glUniform2fv;
   _glUniform2fv = glUniform2fv;
   _glUniform3fv = glUniform3fv;
   _glUniform3fv = glUniform3fv;
   _glUniform4fv = glUniform4fv;
   _glUniform4fv = glUniform4fv;
+  _glUniform1iv = glUniform1iv;
+  _glUniform2iv = glUniform2iv;
+  _glUniform3iv = glUniform3iv;
+  _glUniform4iv = glUniform4iv;
   _glUniformMatrix3fv = glUniformMatrix3fv;
   _glUniformMatrix3fv = glUniformMatrix3fv;
   _glUniformMatrix4fv = glUniformMatrix4fv;
   _glUniformMatrix4fv = glUniformMatrix4fv;
   _glValidateProgram = glValidateProgram;
   _glValidateProgram = glValidateProgram;

+ 8 - 0
panda/src/glstuff/glGraphicsStateGuardian_src.h

@@ -175,6 +175,10 @@ typedef void (APIENTRYP PFNGLUNIFORM1IVPROC) (GLint location, GLsizei count, con
 typedef void (APIENTRYP PFNGLUNIFORM2IVPROC) (GLint location, GLsizei count, const GLint *value);
 typedef void (APIENTRYP PFNGLUNIFORM2IVPROC) (GLint location, GLsizei count, const GLint *value);
 typedef void (APIENTRYP PFNGLUNIFORM3IVPROC) (GLint location, GLsizei count, const GLint *value);
 typedef void (APIENTRYP PFNGLUNIFORM3IVPROC) (GLint location, GLsizei count, const GLint *value);
 typedef void (APIENTRYP PFNGLUNIFORM4IVPROC) (GLint location, GLsizei count, const GLint *value);
 typedef void (APIENTRYP PFNGLUNIFORM4IVPROC) (GLint location, GLsizei count, const GLint *value);
+typedef void (APIENTRYP PFNGLUNIFORM1UIVPROC) (GLint location, GLsizei count, const GLuint *value);
+typedef void (APIENTRYP PFNGLUNIFORM2UIVPROC) (GLint location, GLsizei count, const GLuint *value);
+typedef void (APIENTRYP PFNGLUNIFORM3UIVPROC) (GLint location, GLsizei count, const GLuint *value);
+typedef void (APIENTRYP PFNGLUNIFORM4UIVPROC) (GLint location, GLsizei count, const GLuint *value);
 typedef void (APIENTRYP PFNGLUNIFORMMATRIX3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
 typedef void (APIENTRYP PFNGLUNIFORMMATRIX3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
 typedef void (APIENTRYP PFNGLUNIFORMMATRIX4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
 typedef void (APIENTRYP PFNGLUNIFORMMATRIX4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
 typedef void (APIENTRYP PFNGLVALIDATEPROGRAMPROC) (GLuint program);
 typedef void (APIENTRYP PFNGLVALIDATEPROGRAMPROC) (GLuint program);
@@ -984,6 +988,10 @@ public:
   PFNGLUNIFORM2IVPROC _glUniform2iv;
   PFNGLUNIFORM2IVPROC _glUniform2iv;
   PFNGLUNIFORM3IVPROC _glUniform3iv;
   PFNGLUNIFORM3IVPROC _glUniform3iv;
   PFNGLUNIFORM4IVPROC _glUniform4iv;
   PFNGLUNIFORM4IVPROC _glUniform4iv;
+  PFNGLUNIFORM1UIVPROC _glUniform1uiv;
+  PFNGLUNIFORM2UIVPROC _glUniform2uiv;
+  PFNGLUNIFORM3UIVPROC _glUniform3uiv;
+  PFNGLUNIFORM4UIVPROC _glUniform4uiv;
   PFNGLUNIFORMMATRIX3FVPROC _glUniformMatrix3fv;
   PFNGLUNIFORMMATRIX3FVPROC _glUniformMatrix3fv;
   PFNGLUNIFORMMATRIX4FVPROC _glUniformMatrix4fv;
   PFNGLUNIFORMMATRIX4FVPROC _glUniformMatrix4fv;
   PFNGLVALIDATEPROGRAMPROC _glValidateProgram;
   PFNGLVALIDATEPROGRAMPROC _glValidateProgram;

+ 59 - 2
panda/src/glstuff/glShaderContext_src.cxx

@@ -1501,21 +1501,29 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
       case GL_INT:
       case GL_INT:
       case GL_INT_VEC2:
       case GL_INT_VEC2:
       case GL_INT_VEC3:
       case GL_INT_VEC3:
-      case GL_INT_VEC4: {
+      case GL_INT_VEC4:
+      case GL_UNSIGNED_INT:
+      case GL_UNSIGNED_INT_VEC2:
+      case GL_UNSIGNED_INT_VEC3:
+      case GL_UNSIGNED_INT_VEC4: {
         Shader::ShaderPtrSpec bind;
         Shader::ShaderPtrSpec bind;
         bind._id = arg_id;
         bind._id = arg_id;
         switch (param_type) {
         switch (param_type) {
           case GL_BOOL:
           case GL_BOOL:
           case GL_INT:
           case GL_INT:
+          case GL_UNSIGNED_INT:
           case GL_FLOAT:      bind._dim[1] = 1; break;
           case GL_FLOAT:      bind._dim[1] = 1; break;
           case GL_BOOL_VEC2:
           case GL_BOOL_VEC2:
           case GL_INT_VEC2:
           case GL_INT_VEC2:
+          case GL_UNSIGNED_INT_VEC2:
           case GL_FLOAT_VEC2: bind._dim[1] = 2; break;
           case GL_FLOAT_VEC2: bind._dim[1] = 2; break;
           case GL_BOOL_VEC3:
           case GL_BOOL_VEC3:
           case GL_INT_VEC3:
           case GL_INT_VEC3:
+          case GL_UNSIGNED_INT_VEC3:
           case GL_FLOAT_VEC3: bind._dim[1] = 3; break;
           case GL_FLOAT_VEC3: bind._dim[1] = 3; break;
           case GL_BOOL_VEC4:
           case GL_BOOL_VEC4:
           case GL_INT_VEC4:
           case GL_INT_VEC4:
+          case GL_UNSIGNED_INT_VEC4:
           case GL_FLOAT_VEC4: bind._dim[1] = 4; break;
           case GL_FLOAT_VEC4: bind._dim[1] = 4; break;
           case GL_FLOAT_MAT3: bind._dim[1] = 9; break;
           case GL_FLOAT_MAT3: bind._dim[1] = 9; break;
           case GL_FLOAT_MAT4: bind._dim[1] = 16; break;
           case GL_FLOAT_MAT4: bind._dim[1] = 16; break;
@@ -1525,6 +1533,12 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
         case GL_BOOL_VEC2:
         case GL_BOOL_VEC2:
         case GL_BOOL_VEC3:
         case GL_BOOL_VEC3:
         case GL_BOOL_VEC4:
         case GL_BOOL_VEC4:
+        case GL_UNSIGNED_INT:
+        case GL_UNSIGNED_INT_VEC2:
+        case GL_UNSIGNED_INT_VEC3:
+        case GL_UNSIGNED_INT_VEC4:
+          bind._type = Shader::SPT_uint;
+          break;
         case GL_INT:
         case GL_INT:
         case GL_INT_VEC2:
         case GL_INT_VEC2:
         case GL_INT_VEC3:
         case GL_INT_VEC3:
@@ -1604,6 +1618,10 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
     case GL_INT_VEC2:
     case GL_INT_VEC2:
     case GL_INT_VEC3:
     case GL_INT_VEC3:
     case GL_INT_VEC4:
     case GL_INT_VEC4:
+    case GL_UNSIGNED_INT:
+    case GL_UNSIGNED_INT_VEC2:
+    case GL_UNSIGNED_INT_VEC3:
+    case GL_UNSIGNED_INT_VEC4:
     case GL_FLOAT:
     case GL_FLOAT:
     case GL_FLOAT_VEC2:
     case GL_FLOAT_VEC2:
     case GL_FLOAT_VEC3:
     case GL_FLOAT_VEC3:
@@ -1633,6 +1651,12 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
       case GL_BOOL_VEC2:
       case GL_BOOL_VEC2:
       case GL_BOOL_VEC3:
       case GL_BOOL_VEC3:
       case GL_BOOL_VEC4:
       case GL_BOOL_VEC4:
+      case GL_UNSIGNED_INT:
+      case GL_UNSIGNED_INT_VEC2:
+      case GL_UNSIGNED_INT_VEC3:
+      case GL_UNSIGNED_INT_VEC4:
+        bind._type = Shader::SPT_uint;
+        break;
       case GL_INT:
       case GL_INT:
       case GL_INT_VEC2:
       case GL_INT_VEC2:
       case GL_INT_VEC3:
       case GL_INT_VEC3:
@@ -2003,6 +2027,8 @@ issue_parameters(int altered) {
         return;
         return;
       }
       }
 
 
+      nassertd(spec._dim[1] > 0) continue;
+
       GLint p = spec._id._seqno;
       GLint p = spec._id._seqno;
       int array_size = min(spec._dim[0], (int)ptr_data->_size / spec._dim[1]);
       int array_size = min(spec._dim[0], (int)ptr_data->_size / spec._dim[1]);
       switch (spec._type) {
       switch (spec._type) {
@@ -2019,6 +2045,14 @@ issue_parameters(int altered) {
             }
             }
             break;
             break;
 
 
+          case Shader::SPT_uint:
+            // Convert unsigned int data to float data.
+            data = (float*) alloca(sizeof(float) * array_size * spec._dim[1]);
+            for (int i = 0; i < (array_size * spec._dim[1]); ++i) {
+              data[i] = (float)(((unsigned int*)ptr_data->_ptr)[i]);
+            }
+            break;
+
           case Shader::SPT_double:
           case Shader::SPT_double:
             // Downgrade double data to float data.
             // Downgrade double data to float data.
             data = (float*) alloca(sizeof(float) * array_size * spec._dim[1]);
             data = (float*) alloca(sizeof(float) * array_size * spec._dim[1]);
@@ -2048,7 +2082,8 @@ issue_parameters(int altered) {
         break;
         break;
 
 
       case Shader::SPT_int:
       case Shader::SPT_int:
-        if (ptr_data->_type != Shader::SPT_int) {
+        if (ptr_data->_type != Shader::SPT_int &&
+            ptr_data->_type != Shader::SPT_uint) {
           GLCAT.error()
           GLCAT.error()
             << "Cannot pass floating-point data to integer shader input '" << spec._id._name << "'\n";
             << "Cannot pass floating-point data to integer shader input '" << spec._id._name << "'\n";
 
 
@@ -2068,6 +2103,28 @@ issue_parameters(int altered) {
         }
         }
         break;
         break;
 
 
+      case Shader::SPT_uint:
+        if (ptr_data->_type != Shader::SPT_uint &&
+            ptr_data->_type != Shader::SPT_int) {
+          GLCAT.error()
+            << "Cannot pass floating-point data to integer shader input '" << spec._id._name << "'\n";
+
+          // Deactivate it to make sure the user doesn't get flooded with this
+          // error.
+          spec._dep[0] = 0;
+          spec._dep[1] = 0;
+
+        } else {
+          switch (spec._dim[1]) {
+          case 1: _glgsg->_glUniform1uiv(p, array_size, (GLuint *)ptr_data->_ptr); continue;
+          case 2: _glgsg->_glUniform2uiv(p, array_size, (GLuint *)ptr_data->_ptr); continue;
+          case 3: _glgsg->_glUniform3uiv(p, array_size, (GLuint *)ptr_data->_ptr); continue;
+          case 4: _glgsg->_glUniform4uiv(p, array_size, (GLuint *)ptr_data->_ptr); continue;
+          }
+          nassertd(false) continue;
+        }
+        break;
+
       case Shader::SPT_double:
       case Shader::SPT_double:
         GLCAT.error() << "Passing double-precision shader inputs to GLSL shaders is not currently supported\n";
         GLCAT.error() << "Passing double-precision shader inputs to GLSL shaders is not currently supported\n";
 
 

+ 1 - 0
panda/src/gobj/shader.h

@@ -346,6 +346,7 @@ public:
     SPT_float,
     SPT_float,
     SPT_double,
     SPT_double,
     SPT_int,
     SPT_int,
+    SPT_uint,
     SPT_unknown
     SPT_unknown
   };
   };
 
 

+ 2 - 3
tests/display/test_glsl_shader.py

@@ -183,7 +183,6 @@ def test_glsl_int(gsg):
     run_glsl_test(gsg, code, preamble, inputs)
     run_glsl_test(gsg, code, preamble, inputs)
 
 
 
 
[email protected]
 def test_glsl_uint(gsg):
 def test_glsl_uint(gsg):
     #TODO: fix passing uints greater than intmax
     #TODO: fix passing uints greater than intmax
     inputs = dict(
     inputs = dict(
@@ -191,8 +190,8 @@ def test_glsl_uint(gsg):
         intmax=0x7fffffff,
         intmax=0x7fffffff,
     )
     )
     preamble = """
     preamble = """
-    uniform unsigned int zero;
-    uniform unsigned int intmax;
+    uniform uint zero;
+    uniform uint intmax;
     """
     """
     code = """
     code = """
     assert(zero == 0);
     assert(zero == 0);