From cd79de19b2f41a36dc454a620097c56021ae098c Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 19 Aug 2014 20:22:57 +0000 Subject: [PATCH] Add more parameters for binding images to shaders. --- panda/src/glstuff/glShaderContext_src.cxx | 80 ++++--- panda/src/glstuff/glTextureContext_src.I | 1 - panda/src/glstuff/glTextureContext_src.cxx | 17 +- panda/src/glstuff/glTextureContext_src.h | 7 +- panda/src/pgraph/nodePath.cxx | 262 +-------------------- panda/src/pgraph/nodePath.h | 31 +-- panda/src/pgraph/shaderInput.I | 189 ++++++++++++--- panda/src/pgraph/shaderInput.h | 17 +- 8 files changed, 248 insertions(+), 356 deletions(-) diff --git a/panda/src/glstuff/glShaderContext_src.cxx b/panda/src/glstuff/glShaderContext_src.cxx index bc8c515453..f8dadb991f 100755 --- a/panda/src/glstuff/glShaderContext_src.cxx +++ b/panda/src/glstuff/glShaderContext_src.cxx @@ -1153,9 +1153,14 @@ disable_shader_texture_bindings() { if (gl_enable_memory_barriers) { for (int i = 0; i < num_image_units; ++i) { - // We don't distinguish between read-only and read-write/write-only - // image access, so we have to assume that the shader wrote to it. - _glsl_img_textures[i]->mark_incoherent(); + const InternalName *name = _glsl_img_inputs[i]; + const ShaderInput *input = _glgsg->_target_shader->get_shader_input(name); + + if ((input->_access & ShaderInput::A_write) != 0) { + _glsl_img_textures[i]->mark_incoherent(true); + } else { + _glsl_img_textures[i]->mark_incoherent(false); + } _glsl_img_textures[i] = NULL; } } @@ -1193,21 +1198,18 @@ update_shader_texture_bindings(ShaderContext *prev) { int num_image_units = min(_glsl_img_inputs.size(), (size_t)_glgsg->_max_image_units); if (num_image_units > 0) { - GLuint *multi_img = NULL; - // If we support multi-bind, prepare an array. - if (_glgsg->_supports_multi_bind) { - 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 = _glgsg->_target_shader->get_shader_input_texture(name); + const ShaderInput *input = _glgsg->_target_shader->get_shader_input(name); + Texture *tex = input->get_texture(); GLuint gl_tex = 0; + CLP(TextureContext) *gtc; + if (tex != NULL) { int view = _glgsg->get_current_tex_view_offset(); - CLP(TextureContext) *gtc = DCAST(CLP(TextureContext), tex->prepare_now(view, _glgsg->_prepared_objects, _glgsg)); + gtc = DCAST(CLP(TextureContext), tex->prepare_now(view, _glgsg->_prepared_objects, _glgsg)); if (gtc != (TextureContext*)NULL) { _glsl_img_textures[i] = gtc; @@ -1220,26 +1222,44 @@ update_shader_texture_bindings(ShaderContext *prev) { } } - if (multi_img != NULL) { - // Put in array so we can multi-bind later. - multi_img[i] = gl_tex; - + if (gl_tex == 0) { + _glgsg->_glBindImageTexture(i, 0, 0, GL_FALSE, 0, GL_READ_ONLY, GL_R8); } 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) { - _glgsg->_glBindImageTexture(i, 0, 0, GL_FALSE, 0, GL_READ_ONLY, GL_R8); - } else { - //TODO: automatically convert to sized type instead of plain GL_RGBA - // If a base type is used, it will crash. - GLint internal_format = _glgsg->get_internal_image_format(tex); - _glgsg->_glBindImageTexture(i, gl_tex, 0, GL_TRUE, 0, GL_READ_WRITE, internal_format); - } - } - } + //TODO: automatically convert to sized type instead of plain GL_RGBA + // If a base type is used, it will crash. + if (gtc->_internal_format == GL_RGBA || gtc->_internal_format == GL_RGB) { + GLCAT.error() + << "Texture " << tex->get_name() << " has an unsized format. Textures bound " + << "to a shader as an image need a sized format.\n"; - if (multi_img != NULL) { - _glgsg->_glBindImageTextures(0, num_image_units, multi_img); - delete[] multi_img; + // This may not actually be right, but may still prevent a crash. + if (gtc->_internal_format == GL_RGBA) { + gtc->_internal_format = GL_RGBA8; + } else { + gtc->_internal_format = GL_RGB8; + } + } + + GLenum access = GL_READ_ONLY; + GLboolean layered = (input->_access & ShaderInput::A_layered) != 0; + + if ((input->_access & ShaderInput::A_read) != 0 && + (input->_access & ShaderInput::A_write) != 0) { + access = GL_READ_WRITE; + + } else if ((input->_access & ShaderInput::A_read) != 0) { + access = GL_READ_ONLY; + + } else if ((input->_access & ShaderInput::A_write) != 0) { + access = GL_WRITE_ONLY; + + } else { + access = GL_READ_ONLY; + gl_tex = 0; + } + _glgsg->_glBindImageTexture(i, gl_tex, input->_bind_level, layered, + input->_bind_layer, access, gtc->_internal_format); + } } } #endif @@ -1332,7 +1352,7 @@ update_shader_texture_bindings(ShaderContext *prev) { #ifndef OPENGLES if (barriers != 0) { - // Issue a memory barrier. + // Issue a memory barrier prior to this shader's execution. _glgsg->issue_memory_barrier(barriers); } #endif diff --git a/panda/src/glstuff/glTextureContext_src.I b/panda/src/glstuff/glTextureContext_src.I index 50704ce14e..687a2e1f3b 100644 --- a/panda/src/glstuff/glTextureContext_src.I +++ b/panda/src/glstuff/glTextureContext_src.I @@ -28,7 +28,6 @@ CLP(TextureContext)(CLP(GraphicsStateGuardian) *glgsg, glGenTextures(1, &_index); _handle = 0; - _needs_barrier = false; _has_storage = false; _immutable = false; _uses_mipmaps = false; diff --git a/panda/src/glstuff/glTextureContext_src.cxx b/panda/src/glstuff/glTextureContext_src.cxx index 30effdd052..4c42ab07c8 100644 --- a/panda/src/glstuff/glTextureContext_src.cxx +++ b/panda/src/glstuff/glTextureContext_src.cxx @@ -87,7 +87,6 @@ reset_data() { _handle = 0; _handle_resident = false; - _needs_barrier = false; _has_storage = false; _immutable = false; @@ -169,15 +168,25 @@ needs_barrier(GLbitfield barrier) { // Function: GLTextureContext::mark_incoherent // Access: Public // Description: Mark a texture as needing a memory barrier, since -// a non-coherent write just happened to it. +// a non-coherent read or write just happened to it. +// If 'wrote' is true, it was written to. //////////////////////////////////////////////////////////////////// void CLP(TextureContext):: -mark_incoherent() { +mark_incoherent(bool wrote) { if (!gl_enable_memory_barriers) { return; } - _glgsg->_textures_needing_fetch_barrier.insert(this); + // If we only read from it, the next read operation won't need + // another barrier, since it'll be reading the same data. + if (wrote) { + _glgsg->_textures_needing_fetch_barrier.insert(this); + } + + // We could still write to it before we read from it, so we have + // to always insert these barriers. This could be slightly + // optimized so that we don't issue a barrier between consecutive + // image reads, but that may not be worth the trouble. _glgsg->_textures_needing_image_access_barrier.insert(this); _glgsg->_textures_needing_update_barrier.insert(this); _glgsg->_textures_needing_framebuffer_barrier.insert(this); diff --git a/panda/src/glstuff/glTextureContext_src.h b/panda/src/glstuff/glTextureContext_src.h index 92e90a8276..3eb7515297 100644 --- a/panda/src/glstuff/glTextureContext_src.h +++ b/panda/src/glstuff/glTextureContext_src.h @@ -40,7 +40,7 @@ public: CONSTEXPR bool needs_barrier(GLbitfield barrier) { return false; }; #else bool needs_barrier(GLbitfield barrier); - void mark_incoherent(); + void mark_incoherent(bool wrote); #endif // This is the GL "name" of the texture object. @@ -50,11 +50,6 @@ public: GLuint64 _handle; bool _handle_resident; - // This is true if the texture was recently written to in a - // non-coherent way, and Panda may have to call glMemoryBarrier - // for the results of this write to become visible. - bool _needs_barrier; - // These are the parameters that we specified with the last // glTexImage2D() or glTexStorage2D() call. If none of these have // changed, we can reload the texture image with a glTexSubImage2D(). diff --git a/panda/src/pgraph/nodePath.cxx b/panda/src/pgraph/nodePath.cxx index 2e88f06184..3aae0f7ba6 100644 --- a/panda/src/pgraph/nodePath.cxx +++ b/panda/src/pgraph/nodePath.cxx @@ -3995,6 +3995,16 @@ set_shader_input(const InternalName *id, Texture *tex, int priority) { set_shader_input(new ShaderInput(id,tex,priority)); } +//////////////////////////////////////////////////////////////////// +// Function: NodePath::set_shader_input +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +void NodePath:: +set_shader_input(const InternalName *id, Texture *tex, bool read, bool write, int z, int n, int priority) { + set_shader_input(new ShaderInput(id,tex,read,write,z,n,priority)); +} + //////////////////////////////////////////////////////////////////// // Function: NodePath::set_shader_input // Access: Published @@ -4025,258 +4035,6 @@ set_shader_input(const InternalName *id, PN_stdfloat n1, PN_stdfloat n2, PN_stdf set_shader_input(new ShaderInput(id, LVecBase4(n1, n2, n3, n4), priority)); } -//////////////////////////////////////////////////////////////////// -// Function: NodePath::set_shader_input -// Access: Published -// Description: -//////////////////////////////////////////////////////////////////// -void NodePath:: -set_shader_input(const string &id, const PTA_float &v, int priority) { - set_shader_input(new ShaderInput(InternalName::make(id),v,priority)); -} - -//////////////////////////////////////////////////////////////////// -// Function: NodePath::set_shader_input -// Access: Published -// Description: -//////////////////////////////////////////////////////////////////// -void NodePath:: -set_shader_input(const string &id, const PTA_double &v, int priority) { - set_shader_input(new ShaderInput(InternalName::make(id),v,priority)); -} - -//////////////////////////////////////////////////////////////////// -// Function: NodePath::set_shader_input -// Access: Published -// Description: -//////////////////////////////////////////////////////////////////// -void NodePath:: -set_shader_input(const string &id, const PTA_int &v, int priority) { - set_shader_input(new ShaderInput(InternalName::make(id),v,priority)); -} - -//////////////////////////////////////////////////////////////////// -// Function: NodePath::set_shader_input -// Access: Published -// Description: -//////////////////////////////////////////////////////////////////// -void NodePath:: -set_shader_input(const string &id, const PTA_LVecBase4 &v, int priority) { - set_shader_input(new ShaderInput(InternalName::make(id),v,priority)); -} - -//////////////////////////////////////////////////////////////////// -// Function: NodePath::set_shader_input -// Access: Published -// Description: -//////////////////////////////////////////////////////////////////// -void NodePath:: -set_shader_input(const string &id, const PTA_LVecBase3 &v, int priority) { - set_shader_input(new ShaderInput(InternalName::make(id),v,priority)); -} - - -//////////////////////////////////////////////////////////////////// -// Function: NodePath::set_shader_input -// Access: Published -// Description: -//////////////////////////////////////////////////////////////////// -void NodePath:: -set_shader_input(const string &id, const PTA_LVecBase2 &v, int priority) { - set_shader_input(new ShaderInput(InternalName::make(id),v,priority)); -} - -//////////////////////////////////////////////////////////////////// -// Function: NodePath::set_shader_input -// Access: Published -// Description: -//////////////////////////////////////////////////////////////////// -void NodePath:: -set_shader_input(const string &id, const LVecBase4 &v, int priority) { - set_shader_input(new ShaderInput(InternalName::make(id),v,priority)); -} - -//////////////////////////////////////////////////////////////////// -// Function: NodePath::set_shader_input -// Access: Published -// Description: -//////////////////////////////////////////////////////////////////// -void NodePath:: -set_shader_input(const string &id, const LVecBase3 &v, int priority) { - set_shader_input(new ShaderInput(InternalName::make(id),v,priority)); -} - - -//////////////////////////////////////////////////////////////////// -// Function: NodePath::set_shader_input -// Access: Published -// Description: -//////////////////////////////////////////////////////////////////// -void NodePath:: -set_shader_input(const string &id, const PTA_LVecBase4i &v, int priority) { - set_shader_input(new ShaderInput(InternalName::make(id),v,priority)); -} - -//////////////////////////////////////////////////////////////////// -// Function: NodePath::set_shader_input -// Access: Published -// Description: -//////////////////////////////////////////////////////////////////// -void NodePath:: -set_shader_input(const string &id, const PTA_LVecBase3i &v, int priority) { - set_shader_input(new ShaderInput(InternalName::make(id),v,priority)); -} - - -//////////////////////////////////////////////////////////////////// -// Function: NodePath::set_shader_input -// Access: Published -// Description: -//////////////////////////////////////////////////////////////////// -void NodePath:: -set_shader_input(const string &id, const PTA_LVecBase2i &v, int priority) { - set_shader_input(new ShaderInput(InternalName::make(id),v,priority)); -} - -//////////////////////////////////////////////////////////////////// -// Function: NodePath::set_shader_input -// Access: Published -// Description: -//////////////////////////////////////////////////////////////////// -void NodePath:: -set_shader_input(const string &id, const LVecBase4i &v, int priority) { - set_shader_input(new ShaderInput(InternalName::make(id),v,priority)); -} - -//////////////////////////////////////////////////////////////////// -// Function: NodePath::set_shader_input -// Access: Published -// Description: -//////////////////////////////////////////////////////////////////// -void NodePath:: -set_shader_input(const string &id, const LVecBase3i &v, int priority) { - set_shader_input(new ShaderInput(InternalName::make(id),v,priority)); -} - -//////////////////////////////////////////////////////////////////// -// Function: NodePath::set_shader_input -// Access: Published -// Description: -//////////////////////////////////////////////////////////////////// -void NodePath:: -set_shader_input(const string &id, const LVecBase2i &v, int priority) { - set_shader_input(new ShaderInput(InternalName::make(id),v,priority)); -} - -//////////////////////////////////////////////////////////////////// -// Function: NodePath::set_shader_input -// Access: Published -// Description: -//////////////////////////////////////////////////////////////////// -void NodePath:: -set_shader_input(const string &id, const LVecBase2 &v, int priority) { - set_shader_input(new ShaderInput(InternalName::make(id),v,priority)); -} - -//////////////////////////////////////////////////////////////////// -// Function: NodePath::set_shader_input -// Access: Published -// Description: -//////////////////////////////////////////////////////////////////// -void NodePath:: -set_shader_input(const string &id, const PTA_LMatrix4 &v, int priority) { - set_shader_input(new ShaderInput(InternalName::make(id),v,priority)); -} - -//////////////////////////////////////////////////////////////////// -// Function: NodePath::set_shader_input -// Access: Published -// Description: -//////////////////////////////////////////////////////////////////// -void NodePath:: -set_shader_input(const string &id, const PTA_LMatrix3 &v, int priority) { - set_shader_input(new ShaderInput(InternalName::make(id),v,priority)); -} - -//////////////////////////////////////////////////////////////////// -// Function: NodePath::set_shader_input -// Access: Published -// Description: -//////////////////////////////////////////////////////////////////// -void NodePath:: -set_shader_input(const string &id, const LMatrix4 &v, int priority) { - set_shader_input(new ShaderInput(InternalName::make(id),v,priority)); -} - -//////////////////////////////////////////////////////////////////// -// Function: NodePath::set_shader_input -// Access: Published -// Description: -//////////////////////////////////////////////////////////////////// -void NodePath:: -set_shader_input(const string &id, const LMatrix3 &v, int priority) { - set_shader_input(new ShaderInput(InternalName::make(id),v,priority)); -} -//////////////////////////////////////////////////////////////////// -// Function: NodePath::set_shader_input -// Access: Published -// Description: -//////////////////////////////////////////////////////////////////// -void NodePath:: -set_shader_input(const string &id, Texture *tex, int priority) { - set_shader_input(new ShaderInput(InternalName::make(id),tex,priority)); -} - -//////////////////////////////////////////////////////////////////// -// Function: NodePath::set_shader_input -// Access: Published -// Description: -//////////////////////////////////////////////////////////////////// -void NodePath:: -set_shader_input(const string &id, const NodePath &np, int priority) { - set_shader_input(new ShaderInput(InternalName::make(id),np,priority)); -} - -//////////////////////////////////////////////////////////////////// -// Function: NodePath::set_shader_input -// Access: Published -// Description: -//////////////////////////////////////////////////////////////////// -void NodePath:: -set_shader_input(const string &id, int n1, int n2, int n3, int n4, int priority) { - set_shader_input(new ShaderInput(InternalName::make(id), LVecBase4i(n1, n2, n3, n4), priority)); -} - -//////////////////////////////////////////////////////////////////// -// Function: NodePath::set_shader_input -// Access: Published -// Description: -//////////////////////////////////////////////////////////////////// -void NodePath:: -set_shader_input(const string &id, PN_stdfloat n1, PN_stdfloat n2, PN_stdfloat n3, PN_stdfloat n4, int priority) { - set_shader_input(new ShaderInput(InternalName::make(id), LVecBase4(n1, n2, n3, n4), priority)); -} - -//////////////////////////////////////////////////////////////////// -// Function: NodePath::get_shader_input -// Access: Published -// Description: -//////////////////////////////////////////////////////////////////// -const ShaderInput *NodePath:: -get_shader_input(const string &id) const { - return get_shader_input(InternalName::make(id)); -} - -//////////////////////////////////////////////////////////////////// -// Function: NodePath::clear_shader_input -// Access: Published -// Description: -//////////////////////////////////////////////////////////////////// -void NodePath:: -clear_shader_input(const string &id) { - clear_shader_input(InternalName::make(id)); -} - //////////////////////////////////////////////////////////////////// // Function: NodePath::set_instance_count // Access: Published diff --git a/panda/src/pgraph/nodePath.h b/panda/src/pgraph/nodePath.h index 5b2b2f3cd5..a89c99d0f1 100644 --- a/panda/src/pgraph/nodePath.h +++ b/panda/src/pgraph/nodePath.h @@ -615,6 +615,7 @@ PUBLISHED: void set_shader_input(const ShaderInput *inp); void set_shader_input(const InternalName *id, Texture *tex, int priority=0); + void set_shader_input(const InternalName *id, Texture *tex, bool read, bool write, int z=-1, int n=0, int priority=0); void set_shader_input(const InternalName *id, const NodePath &np, int priority=0); void set_shader_input(const InternalName *id, const PTA_float &v, int priority=0); void set_shader_input(const InternalName *id, const PTA_double &v, int priority=0); @@ -640,41 +641,13 @@ PUBLISHED: void set_shader_input(const InternalName *id, PN_stdfloat n1, PN_stdfloat n2=0, PN_stdfloat n3=0, PN_stdfloat n4=0, int priority=0); - void set_shader_input(const string &id, Texture *tex, int priority=0); - void set_shader_input(const string &id, const NodePath &np, int priority=0); - void set_shader_input(const string &id, const PTA_float &v, int priority=0); - void set_shader_input(const string &id, const PTA_double &v, int priority=0); - void set_shader_input(const string &id, const PTA_int &v, int priority=0); - void set_shader_input(const string &id, const PTA_LVecBase4 &v, int priority=0); - void set_shader_input(const string &id, const PTA_LVecBase3 &v, int priority=0); - void set_shader_input(const string &id, const PTA_LVecBase2 &v, int priority=0); - void set_shader_input(const string &id, const PTA_LMatrix4 &v, int priority=0); - void set_shader_input(const string &id, const PTA_LMatrix3 &v, int priority=0); - void set_shader_input(const string &id, const LVecBase4 &v, int priority=0); - void set_shader_input(const string &id, const LVecBase3 &v, int priority=0); - void set_shader_input(const string &id, const LVecBase2 &v, int priority=0); - void set_shader_input(const string &id, const LMatrix4 &v, int priority=0); - void set_shader_input(const string &id, const LMatrix3 &v, int priority=0); - void set_shader_input(const string &id, const PTA_LVecBase4i &v, int priority=0); - void set_shader_input(const string &id, const PTA_LVecBase3i &v, int priority=0); - void set_shader_input(const string &id, const PTA_LVecBase2i &v, int priority=0); - void set_shader_input(const string &id, const LVecBase4i &v, int priority=0); - void set_shader_input(const string &id, const LVecBase3i &v, int priority=0); - void set_shader_input(const string &id, const LVecBase2i &v, int priority=0); - void set_shader_input(const string &id, int n1, int n2=0, int n3=0, - int n4=0, int priority=0); - void set_shader_input(const string &id, PN_stdfloat n1, PN_stdfloat n2=0, - PN_stdfloat n3=0, PN_stdfloat n4=0, int priority=0); - void clear_shader_input(const InternalName *id); - void clear_shader_input(const string &id); void set_instance_count(int instance_count); const Shader *get_shader() const; const ShaderInput *get_shader_input(const InternalName *id) const; - const ShaderInput *get_shader_input(const string &id) const; const int get_instance_count() const; - + void set_tex_transform(TextureStage *stage, const TransformState *transform); void clear_tex_transform(); void clear_tex_transform(TextureStage *stage); diff --git a/panda/src/pgraph/shaderInput.I b/panda/src/pgraph/shaderInput.I index 21dd429695..8268d8a78c 100644 --- a/panda/src/pgraph/shaderInput.I +++ b/panda/src/pgraph/shaderInput.I @@ -31,7 +31,10 @@ INLINE ShaderInput:: ShaderInput(const InternalName *name, int priority) : _name(name), _type(M_invalid), - _priority(priority) + _priority(priority), + _bind_layer(0), + _bind_level(0), + _access(A_read) { } @@ -45,10 +48,42 @@ ShaderInput(const InternalName *name, Texture *tex, int priority) : _name(name), _type(M_texture), _priority(priority), - _stored_texture(tex) + _stored_texture(tex), + _bind_layer(0), + _bind_level(0), + _access(A_read | A_write | A_layered) { } +//////////////////////////////////////////////////////////////////// +// Function: ShaderInput::Constructor +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +INLINE ShaderInput:: +ShaderInput(const InternalName *name, Texture *tex, bool read, bool write, int z, int n, int priority) : + _name(name), + _type(M_texture), + _priority(priority), + _stored_texture(tex), + _bind_layer(z), + _bind_level(n), + _access(0) +{ + if (read) { + _access |= A_read; + } + if (write) { + _access |= A_write; + } + if (z >= 0) { + _bind_layer = z; + } else { + _bind_layer = 0; + _access |= A_layered; + } +} + //////////////////////////////////////////////////////////////////// // Function: ShaderInput::Constructor // Access: Published @@ -59,7 +94,10 @@ ShaderInput(const InternalName *name, const NodePath &np, int priority) : _name(name), _type(M_nodepath), _priority(priority), - _stored_nodepath(np) + _stored_nodepath(np), + _bind_layer(0), + _bind_level(0), + _access(A_read) { } @@ -73,7 +111,10 @@ ShaderInput(const InternalName *name, const PTA_float &ptr, int priority) : _name(name), _type(M_numeric), _priority(priority), - _stored_ptr(ptr) + _stored_ptr(ptr), + _bind_layer(0), + _bind_level(0), + _access(A_read) { } @@ -87,7 +128,10 @@ ShaderInput(const InternalName *name, const PTA_LVecBase4f &ptr, int priority) : _name(name), _type(M_numeric), _priority(priority), - _stored_ptr(ptr) + _stored_ptr(ptr), + _bind_layer(0), + _bind_level(0), + _access(A_read) { } @@ -101,7 +145,10 @@ ShaderInput(const InternalName *name, const PTA_LVecBase3f &ptr, int priority) : _name(name), _type(M_numeric), _priority(priority), - _stored_ptr(ptr) + _stored_ptr(ptr), + _bind_layer(0), + _bind_level(0), + _access(A_read) { } @@ -115,7 +162,10 @@ ShaderInput(const InternalName *name, const PTA_LVecBase2f &ptr, int priority) : _name(name), _type(M_numeric), _priority(priority), - _stored_ptr(ptr) + _stored_ptr(ptr), + _bind_layer(0), + _bind_level(0), + _access(A_read) { } @@ -130,7 +180,10 @@ ShaderInput(const InternalName *name, const LVecBase4f &vec, int priority) : _type(M_numeric), _priority(priority), _stored_ptr(vec), - _stored_vector(LCAST(PN_stdfloat, vec)) + _stored_vector(LCAST(PN_stdfloat, vec)), + _bind_layer(0), + _bind_level(0), + _access(A_read) { } @@ -145,7 +198,10 @@ ShaderInput(const InternalName *name, const LVecBase3f &vec, int priority) : _type(M_numeric), _priority(priority), _stored_ptr(vec), - _stored_vector(vec.get_x(), vec.get_y(), vec.get_z(), 0.0) + _stored_vector(vec.get_x(), vec.get_y(), vec.get_z(), 0.0), + _bind_layer(0), + _bind_level(0), + _access(A_read) { } @@ -160,7 +216,10 @@ ShaderInput(const InternalName *name, const LVecBase2f &vec, int priority) : _type(M_numeric), _priority(priority), _stored_ptr(vec), - _stored_vector(vec.get_x(), vec.get_y(), 0.0, 0.0) + _stored_vector(vec.get_x(), vec.get_y(), 0.0, 0.0), + _bind_layer(0), + _bind_level(0), + _access(A_read) { } @@ -174,7 +233,10 @@ ShaderInput(const InternalName *name, const PTA_LMatrix4f &ptr, int priority) : _name(name), _type(M_numeric), _priority(priority), - _stored_ptr(ptr) + _stored_ptr(ptr), + _bind_layer(0), + _bind_level(0), + _access(A_read) { } @@ -188,7 +250,10 @@ ShaderInput(const InternalName *name, const PTA_LMatrix3f &ptr, int priority) : _name(name), _type(M_numeric), _priority(priority), - _stored_ptr(ptr) + _stored_ptr(ptr), + _bind_layer(0), + _bind_level(0), + _access(A_read) { } @@ -202,7 +267,10 @@ ShaderInput(const InternalName *name, const LMatrix4f &mat, int priority) : _name(name), _type(M_numeric), _priority(priority), - _stored_ptr(mat) + _stored_ptr(mat), + _bind_layer(0), + _bind_level(0), + _access(A_read) { } @@ -216,7 +284,10 @@ ShaderInput(const InternalName *name, const LMatrix3f &mat, int priority) : _name(name), _type(M_numeric), _priority(priority), - _stored_ptr(mat) + _stored_ptr(mat), + _bind_layer(0), + _bind_level(0), + _access(A_read) { } @@ -230,7 +301,10 @@ ShaderInput(const InternalName *name, const PTA_double &ptr, int priority) : _name(name), _type(M_numeric), _priority(priority), - _stored_ptr(ptr) + _stored_ptr(ptr), + _bind_layer(0), + _bind_level(0), + _access(A_read) { } @@ -244,7 +318,10 @@ ShaderInput(const InternalName *name, const PTA_LVecBase4d &ptr, int priority) : _name(name), _type(M_numeric), _priority(priority), - _stored_ptr(ptr) + _stored_ptr(ptr), + _bind_layer(0), + _bind_level(0), + _access(A_read) { } @@ -258,7 +335,10 @@ ShaderInput(const InternalName *name, const PTA_LVecBase3d &ptr, int priority) : _name(name), _type(M_numeric), _priority(priority), - _stored_ptr(ptr) + _stored_ptr(ptr), + _bind_layer(0), + _bind_level(0), + _access(A_read) { } @@ -272,7 +352,10 @@ ShaderInput(const InternalName *name, const PTA_LVecBase2d &ptr, int priority) : _name(name), _type(M_numeric), _priority(priority), - _stored_ptr(ptr) + _stored_ptr(ptr), + _bind_layer(0), + _bind_level(0), + _access(A_read) { } @@ -287,7 +370,10 @@ ShaderInput(const InternalName *name, const LVecBase4d &vec, int priority) : _type(M_numeric), _priority(priority), _stored_ptr(vec), - _stored_vector(LCAST(PN_stdfloat, vec)) + _stored_vector(LCAST(PN_stdfloat, vec)), + _bind_layer(0), + _bind_level(0), + _access(A_read) { } @@ -302,7 +388,10 @@ ShaderInput(const InternalName *name, const LVecBase3d &vec, int priority) : _type(M_numeric), _priority(priority), _stored_ptr(vec), - _stored_vector(vec.get_x(), vec.get_y(), vec.get_z(), 0.0) + _stored_vector(vec.get_x(), vec.get_y(), vec.get_z(), 0.0), + _bind_layer(0), + _bind_level(0), + _access(A_read) { } @@ -317,7 +406,10 @@ ShaderInput(const InternalName *name, const LVecBase2d &vec, int priority) : _type(M_numeric), _priority(priority), _stored_ptr(vec), - _stored_vector(vec.get_x(), vec.get_y(), 0.0, 0.0) + _stored_vector(vec.get_x(), vec.get_y(), 0.0, 0.0), + _bind_layer(0), + _bind_level(0), + _access(A_read) { } @@ -331,7 +423,10 @@ ShaderInput(const InternalName *name, const PTA_LMatrix4d &ptr, int priority) : _name(name), _type(M_numeric), _priority(priority), - _stored_ptr(ptr) + _stored_ptr(ptr), + _bind_layer(0), + _bind_level(0), + _access(A_read) { } @@ -345,7 +440,10 @@ ShaderInput(const InternalName *name, const PTA_LMatrix3d &ptr, int priority) : _name(name), _type(M_numeric), _priority(priority), - _stored_ptr(ptr) + _stored_ptr(ptr), + _bind_layer(0), + _bind_level(0), + _access(A_read) { } @@ -359,7 +457,10 @@ ShaderInput(const InternalName *name, const LMatrix4d &mat, int priority) : _name(name), _type(M_numeric), _priority(priority), - _stored_ptr(mat) + _stored_ptr(mat), + _bind_layer(0), + _bind_level(0), + _access(A_read) { } @@ -373,7 +474,10 @@ ShaderInput(const InternalName *name, const LMatrix3d &mat, int priority) : _name(name), _type(M_numeric), _priority(priority), - _stored_ptr(mat) + _stored_ptr(mat), + _bind_layer(0), + _bind_level(0), + _access(A_read) { } @@ -387,7 +491,10 @@ ShaderInput(const InternalName *name, const PTA_int &ptr, int priority) : _name(name), _type(M_numeric), _priority(priority), - _stored_ptr(ptr) + _stored_ptr(ptr), + _bind_layer(0), + _bind_level(0), + _access(A_read) { } @@ -401,7 +508,10 @@ ShaderInput(const InternalName *name, const PTA_LVecBase4i &ptr, int priority) : _name(name), _type(M_numeric), _priority(priority), - _stored_ptr(ptr) + _stored_ptr(ptr), + _bind_layer(0), + _bind_level(0), + _access(A_read) { } @@ -415,7 +525,10 @@ ShaderInput(const InternalName *name, const PTA_LVecBase3i &ptr, int priority) : _name(name), _type(M_numeric), _priority(priority), - _stored_ptr(ptr) + _stored_ptr(ptr), + _bind_layer(0), + _bind_level(0), + _access(A_read) { } @@ -429,7 +542,10 @@ ShaderInput(const InternalName *name, const PTA_LVecBase2i &ptr, int priority) : _name(name), _type(M_numeric), _priority(priority), - _stored_ptr(ptr) + _stored_ptr(ptr), + _bind_layer(0), + _bind_level(0), + _access(A_read) { } @@ -444,7 +560,10 @@ ShaderInput(const InternalName *name, const LVecBase4i &vec, int priority) : _type(M_numeric), _priority(priority), _stored_ptr(vec), - _stored_vector((int)vec.get_x(), (int)vec.get_y(), (int)vec.get_z(), (int)vec.get_w()) + _stored_vector((int)vec.get_x(), (int)vec.get_y(), (int)vec.get_z(), (int)vec.get_w()), + _bind_layer(0), + _bind_level(0), + _access(A_read) { } @@ -459,7 +578,10 @@ ShaderInput(const InternalName *name, const LVecBase3i &vec, int priority) : _type(M_numeric), _priority(priority), _stored_ptr(vec), - _stored_vector((int)vec.get_x(), (int)vec.get_y(), (int)vec.get_z(), 0.0) + _stored_vector((int)vec.get_x(), (int)vec.get_y(), (int)vec.get_z(), 0.0), + _bind_layer(0), + _bind_level(0), + _access(A_read) { } @@ -474,7 +596,10 @@ ShaderInput(const InternalName *name, const LVecBase2i &vec, int priority) : _type(M_numeric), _priority(priority), _stored_ptr(vec), - _stored_vector((int)vec.get_x(), (int)vec.get_y(), 0.0, 0.0) + _stored_vector((int)vec.get_x(), (int)vec.get_y(), 0.0, 0.0), + _bind_layer(0), + _bind_level(0), + _access(A_read) { } diff --git a/panda/src/pgraph/shaderInput.h b/panda/src/pgraph/shaderInput.h index 5a7e5135fb..4e1433e239 100644 --- a/panda/src/pgraph/shaderInput.h +++ b/panda/src/pgraph/shaderInput.h @@ -43,10 +43,18 @@ public: INLINE ~ShaderInput(); PUBLISHED: + // Used when binding texture images. + enum AccessFlags { + A_read = 0x01, + A_write = 0x02, + A_layered = 0x04, + }; + static const ShaderInput *get_blank(); INLINE ShaderInput(const InternalName *id, int priority=0); INLINE ShaderInput(const InternalName *id, const NodePath &np, int priority=0); INLINE ShaderInput(const InternalName *id, Texture *tex, int priority=0); + INLINE ShaderInput(const InternalName *id, Texture *tex, bool read, bool write, int z=-1, int n=0, int priority=0); INLINE ShaderInput(const InternalName *id, const PTA_float &ptr, int priority=0); INLINE ShaderInput(const InternalName *id, const PTA_LVecBase4f &ptr, int priority=0); INLINE ShaderInput(const InternalName *id, const PTA_LVecBase3f &ptr, int priority=0); @@ -85,9 +93,9 @@ PUBLISHED: M_nodepath, M_numeric }; - + INLINE const InternalName *get_name() const; - + INLINE int get_value_type() const; INLINE int get_priority() const; INLINE Texture *get_texture() const; @@ -107,6 +115,11 @@ private: NodePath _stored_nodepath; LVecBase4 _stored_vector; +public: + int _bind_layer; + int _bind_level; + int _access; + public: static TypeHandle get_class_type() { return _type_handle;