mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 10:22:45 -04:00
Extremely experimental support for GL_ARB_shader_image_load_store
This commit is contained in:
parent
37f9858e1b
commit
e4747ebf50
@ -1586,6 +1586,35 @@ reset() {
|
|||||||
_supports_anisotropy = true;
|
_supports_anisotropy = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check availability of image read/write functionality in shaders.
|
||||||
|
_max_image_units = 0;
|
||||||
|
if (is_at_least_gl_version(4, 2) || has_extension("GL_ARB_shader_image_load_store")) {
|
||||||
|
_glBindImageTexture = (PFNGLBINDIMAGETEXTUREPROC)
|
||||||
|
get_extension_func(GLPREFIX_QUOTED, "BindImageTexture");
|
||||||
|
|
||||||
|
GLP(GetIntegerv)(GL_MAX_IMAGE_UNITS, &_max_image_units);
|
||||||
|
|
||||||
|
} else if (has_extension("GL_EXT_shader_image_load_store")) {
|
||||||
|
_glBindImageTexture = (PFNGLBINDIMAGETEXTUREPROC)
|
||||||
|
get_extension_func(GLPREFIX_QUOTED, "BindImageTextureEXT");
|
||||||
|
|
||||||
|
GLP(GetIntegerv)(GL_MAX_IMAGE_UNITS_EXT, &_max_image_units);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check availability of multi-bind functions.
|
||||||
|
_supports_multi_bind = false;
|
||||||
|
if (is_at_least_gl_version(4, 4) || has_extension("GL_ARB_multi_bind")) {
|
||||||
|
_glBindImageTextures = (PFNGLBINDIMAGETEXTURESPROC)
|
||||||
|
get_extension_func(GLPREFIX_QUOTED, "BindImageTextures");
|
||||||
|
|
||||||
|
if (_glBindImageTextures != NULL) {
|
||||||
|
_supports_multi_bind = true;
|
||||||
|
} else {
|
||||||
|
GLCAT.warning()
|
||||||
|
<< "ARB_multi_bind advertised as supported by OpenGL runtime, but could not get pointers to extension function.\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
report_my_gl_errors();
|
report_my_gl_errors();
|
||||||
|
|
||||||
if (support_stencil) {
|
if (support_stencil) {
|
||||||
|
@ -170,6 +170,8 @@ typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERPROC) (GLuint index, GLint size,
|
|||||||
typedef void (APIENTRYP PFNGLPROGRAMPARAMETERIEXTPROC) (GLuint program, GLenum pname, GLint value);
|
typedef void (APIENTRYP PFNGLPROGRAMPARAMETERIEXTPROC) (GLuint program, GLenum pname, GLint value);
|
||||||
typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount);
|
typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount);
|
||||||
typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount);
|
typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount);
|
||||||
|
typedef void (APIENTRYP PFNGLBINDIMAGETEXTUREPROC) (GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format);
|
||||||
|
typedef void (APIENTRYP PFNGLBINDIMAGETEXTURESPROC) (GLuint first, GLsizei count, const GLuint *textures);
|
||||||
#endif // OPENGLES
|
#endif // OPENGLES
|
||||||
#endif // __EDG__
|
#endif // __EDG__
|
||||||
|
|
||||||
@ -522,6 +524,8 @@ protected:
|
|||||||
int _num_active_texture_stages;
|
int _num_active_texture_stages;
|
||||||
PN_stdfloat _max_anisotropy;
|
PN_stdfloat _max_anisotropy;
|
||||||
bool _supports_anisotropy;
|
bool _supports_anisotropy;
|
||||||
|
GLint _max_image_units;
|
||||||
|
bool _supports_multi_bind;
|
||||||
|
|
||||||
#ifdef OPENGLES
|
#ifdef OPENGLES
|
||||||
bool _supports_depth24;
|
bool _supports_depth24;
|
||||||
@ -687,6 +691,8 @@ public:
|
|||||||
PFNGLPATCHPARAMETERIPROC _glPatchParameteri;
|
PFNGLPATCHPARAMETERIPROC _glPatchParameteri;
|
||||||
PFNGLDRAWARRAYSINSTANCEDPROC _glDrawArraysInstanced;
|
PFNGLDRAWARRAYSINSTANCEDPROC _glDrawArraysInstanced;
|
||||||
PFNGLDRAWELEMENTSINSTANCEDPROC _glDrawElementsInstanced;
|
PFNGLDRAWELEMENTSINSTANCEDPROC _glDrawElementsInstanced;
|
||||||
|
PFNGLBINDIMAGETEXTUREPROC _glBindImageTexture;
|
||||||
|
PFNGLBINDIMAGETEXTURESPROC _glBindImageTextures;
|
||||||
#endif // OPENGLES
|
#endif // OPENGLES
|
||||||
|
|
||||||
GLenum _edge_clamp;
|
GLenum _edge_clamp;
|
||||||
|
@ -290,9 +290,11 @@ CLP(ShaderContext)(Shader *s, GSG *gsg) : ShaderContext(s) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
gsg->_glUseProgram(_glsl_program);
|
||||||
|
|
||||||
// Analyze the uniforms and put them in _glsl_parameter_map
|
// Analyze the uniforms and put them in _glsl_parameter_map
|
||||||
if (_glsl_parameter_map.size() == 0) {
|
if (_glsl_parameter_map.size() == 0) {
|
||||||
int seqno = 0, texunitno = 0;
|
int seqno = 0, texunitno = 0, imgunitno = 0;
|
||||||
string noprefix;
|
string noprefix;
|
||||||
GLint param_count, param_maxlength, param_size;
|
GLint param_count, param_maxlength, param_size;
|
||||||
GLenum param_type;
|
GLenum param_type;
|
||||||
@ -653,6 +655,28 @@ CLP(ShaderContext)(Shader *s, GSG *gsg) : ShaderContext(s) {
|
|||||||
case GL_INT_VEC4:
|
case GL_INT_VEC4:
|
||||||
GLCAT.warning() << "Panda does not support passing integers to shaders (yet)!\n";
|
GLCAT.warning() << "Panda does not support passing integers to shaders (yet)!\n";
|
||||||
continue;
|
continue;
|
||||||
|
#ifndef OPENGLES
|
||||||
|
case GL_IMAGE_1D_EXT:
|
||||||
|
case GL_IMAGE_2D_EXT:
|
||||||
|
case GL_IMAGE_3D_EXT:
|
||||||
|
case GL_IMAGE_CUBE_EXT:
|
||||||
|
case GL_IMAGE_2D_ARRAY_EXT:
|
||||||
|
case GL_INT_IMAGE_1D_EXT:
|
||||||
|
case GL_INT_IMAGE_2D_EXT:
|
||||||
|
case GL_INT_IMAGE_3D_EXT:
|
||||||
|
case GL_INT_IMAGE_CUBE_EXT:
|
||||||
|
case GL_INT_IMAGE_2D_ARRAY_EXT:
|
||||||
|
case GL_UNSIGNED_INT_IMAGE_1D_EXT:
|
||||||
|
case GL_UNSIGNED_INT_IMAGE_2D_EXT:
|
||||||
|
case GL_UNSIGNED_INT_IMAGE_3D_EXT:
|
||||||
|
case GL_UNSIGNED_INT_IMAGE_CUBE_EXT:
|
||||||
|
case GL_UNSIGNED_INT_IMAGE_2D_ARRAY_EXT:
|
||||||
|
// This won't really change at runtime, so we might as well
|
||||||
|
// bind once and then forget about it.
|
||||||
|
gsg->_glUniform1i(p, imgunitno++);
|
||||||
|
_glsl_img_inputs.push_back(InternalName::make(param_name));
|
||||||
|
continue;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
GLCAT.warning() << "Ignoring unrecognized GLSL parameter type!\n";
|
GLCAT.warning() << "Ignoring unrecognized GLSL parameter type!\n";
|
||||||
}
|
}
|
||||||
@ -793,6 +817,7 @@ CLP(ShaderContext)(Shader *s, GSG *gsg) : ShaderContext(s) {
|
|||||||
s->_var_spec.push_back(bind);
|
s->_var_spec.push_back(bind);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
gsg->_glUseProgram(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
gsg->report_my_gl_errors();
|
gsg->report_my_gl_errors();
|
||||||
@ -1465,6 +1490,51 @@ update_shader_texture_bindings(CLP(ShaderContext) *prev, GSG *gsg) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Now bind all the 'image units'; a bit of an esoteric OpenGL feature right now.
|
||||||
|
int num_image_units = min(_glsl_img_inputs.size(), (size_t)gsg->_max_image_units);
|
||||||
|
|
||||||
|
if (num_image_units > 0 && _shader->get_language() == Shader::SL_GLSL) {
|
||||||
|
GLuint *multi_img = NULL;
|
||||||
|
// If we support multi-bind, prepare an array.
|
||||||
|
if (gsg->_supports_multi_bind && num_image_units > 1) {
|
||||||
|
multi_img = new GLuint[num_image_units];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < num_image_units; ++i) {
|
||||||
|
const InternalName *name = _glsl_img_inputs[i];
|
||||||
|
Texture *tex = gsg->_target_shader->get_shader_input_texture(name);
|
||||||
|
|
||||||
|
GLuint gl_tex = 0;
|
||||||
|
if (tex != NULL) {
|
||||||
|
int view = gsg->get_current_tex_view_offset();
|
||||||
|
|
||||||
|
CLP(TextureContext) *gtc = DCAST(CLP(TextureContext), tex->prepare_now(view, gsg->_prepared_objects, gsg));
|
||||||
|
if (gtc != (TextureContext*)NULL) {
|
||||||
|
gl_tex = gtc->_index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (multi_img != NULL) {
|
||||||
|
// Put in array so we can multi-bind later.
|
||||||
|
multi_img[i] = gl_tex;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// We don't support multi-bind, so bind now in the same way that multi-bind would have done it.
|
||||||
|
if (gl_tex == 0) {
|
||||||
|
gsg->_glBindImageTexture(i, 0, 0, GL_FALSE, 0, GL_READ_ONLY, GL_R8);
|
||||||
|
} else {
|
||||||
|
GLint internal_format = gsg->get_internal_image_format(tex);
|
||||||
|
gsg->_glBindImageTexture(i, gl_tex, 0, GL_TRUE, 0, GL_READ_WRITE, internal_format);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (multi_img != NULL) {
|
||||||
|
gsg->_glBindImageTextures(0, num_image_units, multi_img);
|
||||||
|
delete[] multi_img;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(HAVE_CG) && !defined(OPENGLES)
|
#if defined(HAVE_CG) && !defined(OPENGLES)
|
||||||
cg_report_errors();
|
cg_report_errors();
|
||||||
#endif
|
#endif
|
||||||
|
@ -77,6 +77,8 @@ private:
|
|||||||
|
|
||||||
pvector <GLint> _glsl_parameter_map;
|
pvector <GLint> _glsl_parameter_map;
|
||||||
|
|
||||||
|
pvector<CPT(InternalName)> _glsl_img_inputs;
|
||||||
|
|
||||||
int _stage_offset;
|
int _stage_offset;
|
||||||
// Avoid using this! It merely exists so the
|
// Avoid using this! It merely exists so the
|
||||||
// destructor has access to the extension functions.
|
// destructor has access to the extension functions.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user