shader: Pass built-in array shader input in one go

This applies to `p3d_TextureMatrix[]` and `p3d_ClipPlane[]`

This is more efficient and also works around Apple driver bugs (like #846)

Fixes #883
This commit is contained in:
rdb 2023-09-17 19:12:33 +02:00
parent ba388e2866
commit cb4597ebb8
4 changed files with 21 additions and 32 deletions

View File

@ -710,7 +710,9 @@ issue_parameters(int altered) {
case Shader::SMP_vec2: cgGLSetParameter2fv(p, data); continue;
case Shader::SMP_vec3: cgGLSetParameter3fv(p, data); continue;
case Shader::SMP_vec4: cgGLSetParameter4fv(p, data); continue;
case Shader::SMP_vec4_array: cgGLSetParameterArray4f(p, 0, spec._array_count, data); continue;
case Shader::SMP_mat4_whole: cgGLSetMatrixParameterfc(p, data); continue;
case Shader::SMP_mat4_array: cgGLSetMatrixParameterArrayfc(p, 0, spec._array_count, data); continue;
case Shader::SMP_mat4_transpose: cgGLSetMatrixParameterfr(p, data); continue;
case Shader::SMP_mat4_column: cgGLSetParameter4f(p, data[0], data[4], data[ 8], data[12]); continue;
case Shader::SMP_mat4_upper3x3:

View File

@ -937,27 +937,12 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
return;
}
bind._piece = Shader::SMP_mat4_array;
bind._func = Shader::SMF_first;
bind._part[0] = inverse ? Shader::SMO_inv_texmat_i
: Shader::SMO_texmat_i;
bind._part[1] = Shader::SMO_identity;
// Add it once for each index.
for (bind._index = 0; bind._index < param_size; ++bind._index) {
// It was discovered in #846, that GLSL 4.10 and lower don't seem to
// guarantee that matrices occupy successive locations, and on macOS
// they indeed occupy four locations per element.
// As a big fat hack, we multiply by four on macOS, because this is
// hard to fix on the 1.10 branch. We'll have a proper fix on the
// master branch.
#ifdef __APPLE__
bind._id._seqno = p + bind._index * 4;
#else
bind._id._seqno = p + bind._index;
#endif
_shader->cp_add_mat_spec(bind);
}
return;
bind._array_count = param_size;
} else if (matrix_name.size() > 15 &&
matrix_name.substr(0, 12) == "LightSource[" &&
@ -1222,19 +1207,16 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
<< "p3d_ClipPlane should be vec4 or vec4[]\n";
return;
}
for (int i = 0; i < param_size; ++i) {
Shader::ShaderMatSpec bind;
bind._id = arg_id;
bind._id._seqno = p + i;
bind._piece = Shader::SMP_vec4;
bind._func = Shader::SMF_first;
bind._index = i;
bind._part[0] = Shader::SMO_apiview_clipplane_i;
bind._arg[0] = nullptr;
bind._part[1] = Shader::SMO_identity;
bind._arg[1] = nullptr;
_shader->cp_add_mat_spec(bind);
}
Shader::ShaderMatSpec bind;
bind._id = arg_id;
bind._piece = Shader::SMP_vec4_array;
bind._func = Shader::SMF_first;
bind._part[0] = Shader::SMO_apiview_clipplane_i;
bind._arg[0] = nullptr;
bind._part[1] = Shader::SMO_identity;
bind._arg[1] = nullptr;
bind._array_count = param_size;
_shader->cp_add_mat_spec(bind);
return;
}
if (size > 4 && noprefix.substr(0, 4) == "Fog.") {
@ -2310,7 +2292,9 @@ issue_parameters(int altered) {
case Shader::SMP_vec2: _glgsg->_glUniform2fv(p, 1, data); continue;
case Shader::SMP_vec3: _glgsg->_glUniform3fv(p, 1, data); continue;
case Shader::SMP_vec4: _glgsg->_glUniform4fv(p, 1, data); continue;
case Shader::SMP_vec4_array: _glgsg->_glUniform4fv(p, spec._array_count, data); continue;
case Shader::SMP_mat4_whole: _glgsg->_glUniformMatrix4fv(p, 1, GL_FALSE, data); continue;
case Shader::SMP_mat4_array: _glgsg->_glUniformMatrix4fv(p, spec._array_count, GL_FALSE, data); continue;
case Shader::SMP_mat4_transpose: _glgsg->_glUniformMatrix4fv(p, 1, GL_TRUE, data); continue;
case Shader::SMP_mat4_column: _glgsg->_glUniform4f(p, data[0], data[4], data[8], data[12]); continue;
case Shader::SMP_mat4_upper3x3:

View File

@ -577,7 +577,7 @@ cp_add_mat_spec(ShaderMatSpec &spec) {
// index refer to. (It can't be the case that both parts are arrays.)
int begin[2] = {0, 0};
int end[2] = {1, 1};
if (spec._index > 0) {
if (spec._index > 0 || spec._array_count > 1) {
for (int i = 0; i < 2; ++i) {
if (spec._part[i] == SMO_texmat_i ||
spec._part[i] == SMO_inv_texmat_i ||
@ -592,7 +592,7 @@ cp_add_mat_spec(ShaderMatSpec &spec) {
spec._part[i] == SMO_texscale_i ||
spec._part[i] == SMO_texcolor_i) {
begin[i] = spec._index;
end[i] = spec._index + 1;
end[i] = spec._index + spec._array_count;
}
}
nassertv(end[0] == 1 || end[1] == 1);

View File

@ -296,7 +296,9 @@ public:
SMP_vec2,
SMP_vec3,
SMP_vec4,
SMP_vec4_array,
SMP_mat4_whole,
SMP_mat4_array,
SMP_mat4_transpose,
SMP_mat4_column,
SMP_mat4_upper3x3,
@ -441,6 +443,7 @@ public:
int _index = 0;
ShaderMatPiece _piece;
int _offset = 0;
int _array_count = 1;
};
struct ShaderTexSpec {