glsl: support passing uint variables to shader

This commit is contained in:
rdb 2018-07-17 22:32:34 +02:00
parent 911a549386
commit 06539f5c66
6 changed files with 83 additions and 5 deletions

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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";

View File

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

View File

@ -183,7 +183,6 @@ def test_glsl_int(gsg):
run_glsl_test(gsg, code, preamble, inputs) run_glsl_test(gsg, code, preamble, inputs)
@pytest.mark.xfail
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 uint zero;
uniform unsigned int intmax; uniform uint intmax;
""" """
code = """ code = """
assert(zero == 0); assert(zero == 0);