mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-02 09:52:27 -04:00
Extremely experimental support for GL_ARB_shader_image_load_store
This commit is contained in:
parent
37f9858e1b
commit
e4747ebf50
@ -1584,7 +1584,36 @@ reset() {
|
||||
GLP(GetFloatv)(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &max_anisotropy);
|
||||
_max_anisotropy = (PN_stdfloat)max_anisotropy;
|
||||
_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();
|
||||
|
||||
|
@ -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 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 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 // __EDG__
|
||||
|
||||
@ -522,6 +524,8 @@ protected:
|
||||
int _num_active_texture_stages;
|
||||
PN_stdfloat _max_anisotropy;
|
||||
bool _supports_anisotropy;
|
||||
GLint _max_image_units;
|
||||
bool _supports_multi_bind;
|
||||
|
||||
#ifdef OPENGLES
|
||||
bool _supports_depth24;
|
||||
@ -687,6 +691,8 @@ public:
|
||||
PFNGLPATCHPARAMETERIPROC _glPatchParameteri;
|
||||
PFNGLDRAWARRAYSINSTANCEDPROC _glDrawArraysInstanced;
|
||||
PFNGLDRAWELEMENTSINSTANCEDPROC _glDrawElementsInstanced;
|
||||
PFNGLBINDIMAGETEXTUREPROC _glBindImageTexture;
|
||||
PFNGLBINDIMAGETEXTURESPROC _glBindImageTextures;
|
||||
#endif // OPENGLES
|
||||
|
||||
GLenum _edge_clamp;
|
||||
|
@ -290,9 +290,11 @@ CLP(ShaderContext)(Shader *s, GSG *gsg) : ShaderContext(s) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
gsg->_glUseProgram(_glsl_program);
|
||||
|
||||
// Analyze the uniforms and put them in _glsl_parameter_map
|
||||
if (_glsl_parameter_map.size() == 0) {
|
||||
int seqno = 0, texunitno = 0;
|
||||
int seqno = 0, texunitno = 0, imgunitno = 0;
|
||||
string noprefix;
|
||||
GLint param_count, param_maxlength, param_size;
|
||||
GLenum param_type;
|
||||
@ -653,6 +655,28 @@ CLP(ShaderContext)(Shader *s, GSG *gsg) : ShaderContext(s) {
|
||||
case GL_INT_VEC4:
|
||||
GLCAT.warning() << "Panda does not support passing integers to shaders (yet)!\n";
|
||||
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:
|
||||
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);
|
||||
}
|
||||
}
|
||||
gsg->_glUseProgram(0);
|
||||
}
|
||||
|
||||
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)
|
||||
cg_report_errors();
|
||||
#endif
|
||||
|
@ -77,6 +77,8 @@ private:
|
||||
|
||||
pvector <GLint> _glsl_parameter_map;
|
||||
|
||||
pvector<CPT(InternalName)> _glsl_img_inputs;
|
||||
|
||||
int _stage_offset;
|
||||
// Avoid using this! It merely exists so the
|
||||
// destructor has access to the extension functions.
|
||||
|
Loading…
x
Reference in New Issue
Block a user