Browse Source

Merge branch 'shaderpipeline' into vulkan

rdb 5 years ago
parent
commit
3bc61c1982

+ 4 - 4
panda/src/glstuff/glShaderContext_src.cxx

@@ -2226,7 +2226,7 @@ issue_parameters(int altered) {
         break;
         break;
 
 
       case ShaderType::ST_double:
       case ShaderType::ST_double:
-        GLCAT.error() << "Passing double-precision shader inputs to GLSL shaders is not currently supported\n";
+        GLCAT.error() << "Passing double-precision shader inputs to shaders is not currently supported\n";
 
 
         // Deactivate it to make sure the user doesn't get flooded with this
         // Deactivate it to make sure the user doesn't get flooded with this
         // error.
         // error.
@@ -2816,19 +2816,19 @@ update_shader_texture_bindings(ShaderContext *prev) {
       switch (spec._part) {
       switch (spec._part) {
       case Shader::STO_named_input:
       case Shader::STO_named_input:
         GLCAT.error()
         GLCAT.error()
-          << "Sampler type of GLSL shader input '" << *id << "' does not "
+          << "Sampler type of shader input '" << *id << "' does not "
              "match type of texture " << *tex << ".\n";
              "match type of texture " << *tex << ".\n";
         break;
         break;
 
 
       case Shader::STO_stage_i:
       case Shader::STO_stage_i:
         GLCAT.error()
         GLCAT.error()
-          << "Sampler type of GLSL shader input p3d_Texture" << spec._stage
+          << "Sampler type of shader input p3d_Texture" << spec._stage
           << " does not match type of texture " << *tex << ".\n";
           << " does not match type of texture " << *tex << ".\n";
         break;
         break;
 
 
       case Shader::STO_light_i_shadow_map:
       case Shader::STO_light_i_shadow_map:
         GLCAT.error()
         GLCAT.error()
-          << "Sampler type of GLSL shader input p3d_LightSource[" << spec._stage
+          << "Sampler type of shader input p3d_LightSource[" << spec._stage
           << "].shadowMap does not match type of texture " << *tex << ".\n";
           << "].shadowMap does not match type of texture " << *tex << ".\n";
         break;
         break;
       }
       }

+ 8 - 8
panda/src/gobj/shader.cxx

@@ -1918,7 +1918,7 @@ bind_vertex_input(const InternalName *name, const ::ShaderType *type, int locati
  */
  */
 bool Shader::
 bool Shader::
 bind_parameter(const Parameter &param) {
 bind_parameter(const Parameter &param) {
-  const InternalName *name = param._name;
+  CPT(InternalName) name = param._name;
   const ::ShaderType *type = param._type;
   const ::ShaderType *type = param._type;
   std::string name_str = name->get_name();
   std::string name_str = name->get_name();
 
 
@@ -2141,7 +2141,7 @@ bind_parameter(const Parameter &param) {
       for (size_t i = 0; i < struct_type->get_num_members(); ++i) {
       for (size_t i = 0; i < struct_type->get_num_members(); ++i) {
         const ::ShaderType::Struct::Member &member = struct_type->get_member(i);
         const ::ShaderType::Struct::Member &member = struct_type->get_member(i);
 
 
-        CPT(InternalName) fqname = ((InternalName *)name)->append(member.name);
+        CPT(InternalName) fqname = ((InternalName *)name.p())->append(member.name);
         bind._id._location = param._location + i;
         bind._id._location = param._location + i;
         bind._id._name = fqname->get_name();
         bind._id._name = fqname->get_name();
         bind._id._type = member.type;
         bind._id._type = member.type;
@@ -2260,7 +2260,7 @@ bind_parameter(const Parameter &param) {
           return report_parameter_error(name, type, "expected 'ambient' member");
           return report_parameter_error(name, type, "expected 'ambient' member");
         }
         }
 
 
-        CPT(InternalName) fqname = ((InternalName *)name)->append(member.name);
+        CPT(InternalName) fqname = ((InternalName *)name.p())->append(member.name);
         if (!expect_float_vector(fqname, member.type, 3, 4)) {
         if (!expect_float_vector(fqname, member.type, 3, 4)) {
           return false;
           return false;
         }
         }
@@ -2300,7 +2300,7 @@ bind_parameter(const Parameter &param) {
       for (size_t i = 0; i < num_members; ++i) {
       for (size_t i = 0; i < num_members; ++i) {
         const ::ShaderType::Struct::Member &member = struct_type->get_member(i);
         const ::ShaderType::Struct::Member &member = struct_type->get_member(i);
 
 
-        CPT(InternalName) fqname = ((InternalName *)name)->append(member.name);
+        CPT(InternalName) fqname = ((InternalName *)name.p())->append(member.name);
 
 
         if (member.name == "shadowMap") {
         if (member.name == "shadowMap") {
           if (member.type->as_sampled_image() == nullptr) {
           if (member.type->as_sampled_image() == nullptr) {
@@ -3092,7 +3092,7 @@ bind_parameter(const Parameter &param) {
     for (size_t i = 0; i < struct_type->get_num_members(); ++i) {
     for (size_t i = 0; i < struct_type->get_num_members(); ++i) {
       const ::ShaderType::Struct::Member &member = struct_type->get_member(i);
       const ::ShaderType::Struct::Member &member = struct_type->get_member(i);
 
 
-      PT(InternalName) fqname = ((InternalName *)name)->append(member.name);
+      PT(InternalName) fqname = ((InternalName *)name.p())->append(member.name);
 
 
       // Numeric struct members under GLSL may need a special treatment.
       // Numeric struct members under GLSL may need a special treatment.
       ScalarType scalar_type;
       ScalarType scalar_type;
@@ -3124,7 +3124,7 @@ bind_parameter(const Parameter &param) {
           bind._part[0] = SMO_model_to_apiview;
           bind._part[0] = SMO_model_to_apiview;
           bind._arg[0] = nullptr;
           bind._arg[0] = nullptr;
           bind._part[1] = SMO_mat_constant_x_attrib;
           bind._part[1] = SMO_mat_constant_x_attrib;
-          bind._arg[1] = ((InternalName *)name)->append("shadowViewMatrix");
+          bind._arg[1] = ((InternalName *)name.p())->append("shadowViewMatrix");
         }
         }
         else {
         else {
           bind._func = SMF_first;
           bind._func = SMF_first;
@@ -3211,14 +3211,14 @@ bind_parameter(const Parameter &param) {
   ShaderPtrSpec bind;
   ShaderPtrSpec bind;
   if (type->as_scalar_type(bind._type, bind._dim[0], bind._dim[1], bind._dim[2])) {
   if (type->as_scalar_type(bind._type, bind._dim[0], bind._dim[1], bind._dim[2])) {
     bind._id = param;
     bind._id = param;
-    bind._arg = std::move(name);
+    bind._arg = name;
 
 
     //if (k_prefix) {
     //if (k_prefix) {
     //  // Backward compatibility, disables certain checks.
     //  // Backward compatibility, disables certain checks.
     //  bind._dim[0] = -1;
     //  bind._dim[0] = -1;
     //}
     //}
 
 
-    _ptr_spec.push_back(bind);
+    _ptr_spec.push_back(std::move(bind));
     return true;
     return true;
   }
   }
 
 

+ 0 - 28
panda/src/gobj/shaderType.I

@@ -134,34 +134,6 @@ get_member(size_t i) const {
   return _members[i];
   return _members[i];
 }
 }
 
 
-/**
- * Adds a member to this struct.
- */
-INLINE void ShaderType::Struct::
-add_member(const ShaderType *type, std::string name) {
-  Member member;
-  member.type = type;
-  member.name = std::move(name);
-  member.offset = _members.empty() ? 0 : _members.back().offset + _members.back().type->get_size_bytes();
-  _members.push_back(std::move(member));
-}
-
-/**
- * Adds a member to this struct with a given offset.
- */
-INLINE void ShaderType::Struct::
-add_member(const ShaderType *type, std::string name, uint32_t offset) {
-  pvector<Member>::iterator it = _members.begin();
-  while (it != _members.end() && it->offset < offset) {
-    ++it;
-  }
-  Member member;
-  member.type = type;
-  member.name = std::move(name);
-  member.offset = offset;
-  _members.insert(it, std::move(member));
-}
-
 /**
 /**
  * Constructs an array type from a base type and number of elements.
  * Constructs an array type from a base type and number of elements.
  */
  */

+ 87 - 1
panda/src/gobj/shaderType.cxx

@@ -141,6 +141,14 @@ compare_to_impl(const ShaderType &other) const {
        - (_scalar_type < other_scalar._scalar_type);
        - (_scalar_type < other_scalar._scalar_type);
 }
 }
 
 
+/**
+ * Returns the alignment in bytes of this type in memory, if applicable.
+ */
+int ShaderType::Scalar::
+get_align_bytes() const {
+  return (_scalar_type == ST_double) ? 8 : 4;
+}
+
 /**
 /**
  * Returns true if this type contains the given scalar type.
  * Returns true if this type contains the given scalar type.
  */
  */
@@ -185,6 +193,15 @@ compare_to_impl(const ShaderType &other) const {
        - (_num_components < other_vector._num_components);
        - (_num_components < other_vector._num_components);
 }
 }
 
 
+/**
+ * Returns the alignment in bytes of this type in memory, if applicable.
+ */
+int ShaderType::Vector::
+get_align_bytes() const {
+  int component_align = (_scalar_type == ST_double) ? 8 : 4;
+  return component_align * ((_num_components == 3) ? 4 : _num_components);
+}
+
 /**
 /**
  * Returns true if this type contains the given scalar type.
  * Returns true if this type contains the given scalar type.
  */
  */
@@ -232,6 +249,16 @@ compare_to_impl(const ShaderType &other) const {
        - (_num_columns < other_matrix._num_columns);
        - (_num_columns < other_matrix._num_columns);
 }
 }
 
 
+/**
+ * Returns the alignment in bytes of this type in memory, if applicable.
+ */
+int ShaderType::Matrix::
+get_align_bytes() const {
+  //TODO: needs to be checked
+  int row_align = (_scalar_type == ST_double) ? 32 : 16;
+  return row_align * _num_rows;
+}
+
 /**
 /**
  * Returns the number of in/out locations taken up by in/out variables having
  * Returns the number of in/out locations taken up by in/out variables having
  * this type.
  * this type.
@@ -241,6 +268,36 @@ get_num_interface_locations() const {
   return _num_rows;
   return _num_rows;
 }
 }
 
 
+/**
+ * Adds a member to this struct.
+ */
+void ShaderType::Struct::
+add_member(const ShaderType *type, std::string name) {
+  Member member;
+  member.type = type;
+  member.name = std::move(name);
+  member.offset = _members.empty() ? 0 : _members.back().offset + _members.back().type->get_size_bytes();
+  int alignment = type->get_align_bytes();
+  member.offset += alignment - ((member.offset + (alignment - 1)) % alignment) - 1;
+  _members.push_back(std::move(member));
+}
+
+/**
+ * Adds a member to this struct with a given offset.
+ */
+void ShaderType::Struct::
+add_member(const ShaderType *type, std::string name, uint32_t offset) {
+  pvector<Member>::iterator it = _members.begin();
+  while (it != _members.end() && it->offset < offset) {
+    ++it;
+  }
+  Member member;
+  member.type = type;
+  member.name = std::move(name);
+  member.offset = offset;
+  _members.insert(it, std::move(member));
+}
+
 /**
 /**
  * Returns true if this type contains the given scalar type.
  * Returns true if this type contains the given scalar type.
  */
  */
@@ -295,6 +352,18 @@ compare_to_impl(const ShaderType &other) const {
   return 0;
   return 0;
 }
 }
 
 
+/**
+ * Returns the alignment in bytes of this type in memory, if applicable.
+ */
+int ShaderType::Struct::
+get_align_bytes() const {
+  int align = 16;
+  for (const Member &member : _members) {
+    align = std::max(align, member.type->get_align_bytes());
+  }
+  return align;
+}
+
 /**
 /**
  * Returns the size in bytes of this type in memory, if applicable.  Opaque
  * Returns the size in bytes of this type in memory, if applicable.  Opaque
  * types will return -1.
  * types will return -1.
@@ -376,13 +445,30 @@ compare_to_impl(const ShaderType &other) const {
        - (_num_elements < other_array._num_elements);
        - (_num_elements < other_array._num_elements);
 }
 }
 
 
+/**
+ * Returns the array stride in bytes.
+ */
+int ShaderType::Array::
+get_stride_bytes() const {
+  int element_size = _element_type->get_size_bytes();
+  return (element_size + 15) & ~15;
+}
+
+/**
+ * Returns the alignment in bytes of this type in memory, if applicable.
+ */
+int ShaderType::Array::
+get_align_bytes() const {
+  return get_stride_bytes();
+}
+
 /**
 /**
  * Returns the size in bytes of this type in memory, if applicable.  Opaque
  * Returns the size in bytes of this type in memory, if applicable.  Opaque
  * types will return -1.
  * types will return -1.
  */
  */
 int ShaderType::Array::
 int ShaderType::Array::
 get_size_bytes() const {
 get_size_bytes() const {
-  return _element_type->get_size_bytes() * _num_elements;
+  return get_stride_bytes() * _num_elements;
 }
 }
 
 
 /**
 /**

+ 12 - 2
panda/src/gobj/shaderType.h

@@ -34,6 +34,7 @@ public:
 
 
   virtual void output(std::ostream &out) const=0;
   virtual void output(std::ostream &out) const=0;
 
 
+  virtual int get_align_bytes() const { return 1; }
   virtual int get_size_bytes() const;
   virtual int get_size_bytes() const;
   virtual int get_num_interface_locations() const { return 1; }
   virtual int get_num_interface_locations() const { return 1; }
   virtual int get_num_parameter_locations() const { return 1; }
   virtual int get_num_parameter_locations() const { return 1; }
@@ -129,6 +130,8 @@ public:
 private:
 private:
   virtual int compare_to_impl(const ShaderType &other) const override;
   virtual int compare_to_impl(const ShaderType &other) const override;
 
 
+  virtual int get_align_bytes() const override;
+
   const ScalarType _scalar_type;
   const ScalarType _scalar_type;
 
 
 public:
 public:
@@ -167,6 +170,8 @@ public:
 private:
 private:
   virtual int compare_to_impl(const ShaderType &other) const override;
   virtual int compare_to_impl(const ShaderType &other) const override;
 
 
+  virtual int get_align_bytes() const override;
+
   const ScalarType _scalar_type;
   const ScalarType _scalar_type;
   const uint32_t _num_components;
   const uint32_t _num_components;
 
 
@@ -208,6 +213,8 @@ public:
 private:
 private:
   virtual int compare_to_impl(const ShaderType &other) const override;
   virtual int compare_to_impl(const ShaderType &other) const override;
 
 
+  virtual int get_align_bytes() const override;
+
   const ScalarType _scalar_type;
   const ScalarType _scalar_type;
   const uint32_t _num_rows;
   const uint32_t _num_rows;
   const uint32_t _num_columns;
   const uint32_t _num_columns;
@@ -235,12 +242,13 @@ public:
 
 
   INLINE size_t get_num_members() const;
   INLINE size_t get_num_members() const;
   INLINE const Member &get_member(size_t i) const;
   INLINE const Member &get_member(size_t i) const;
-  INLINE void add_member(const ShaderType *type, std::string name);
-  INLINE void add_member(const ShaderType *type, std::string name, uint32_t offset);
+  void add_member(const ShaderType *type, std::string name);
+  void add_member(const ShaderType *type, std::string name, uint32_t offset);
 
 
   virtual void output(std::ostream &out) const override;
   virtual void output(std::ostream &out) const override;
   virtual int compare_to_impl(const ShaderType &other) const override;
   virtual int compare_to_impl(const ShaderType &other) const override;
 
 
+  virtual int get_align_bytes() const override;
   virtual int get_size_bytes() const override;
   virtual int get_size_bytes() const override;
   virtual int get_num_interface_locations() const override;
   virtual int get_num_interface_locations() const override;
   virtual int get_num_parameter_locations() const override;
   virtual int get_num_parameter_locations() const override;
@@ -292,6 +300,8 @@ public:
   virtual void output(std::ostream &out) const override;
   virtual void output(std::ostream &out) const override;
   virtual int compare_to_impl(const ShaderType &other) const override;
   virtual int compare_to_impl(const ShaderType &other) const override;
 
 
+  int get_stride_bytes() const;
+  virtual int get_align_bytes() const override;
   virtual int get_size_bytes() const override;
   virtual int get_size_bytes() const override;
   virtual int get_num_interface_locations() const override;
   virtual int get_num_interface_locations() const override;
   virtual int get_num_parameter_locations() const override;
   virtual int get_num_parameter_locations() const override;

+ 15 - 0
panda/src/shaderpipeline/shaderModuleSpirV.cxx

@@ -1344,6 +1344,17 @@ r_annotate_struct_layout(InstructionIterator &it, uint32_t type_id) {
     const ShaderType *base_type = member.type;
     const ShaderType *base_type = member.type;
     while (const ShaderType::Array *array_type = base_type->as_array()) {
     while (const ShaderType::Array *array_type = base_type->as_array()) {
       base_type = array_type->get_element_type();
       base_type = array_type->get_element_type();
+
+      // Also make sure there's an ArrayStride decoration for this array.
+      uint32_t array_type_id = _type_map[array_type];
+      Definition &array_def = _defs[array_type_id];
+
+      if (array_def._array_stride == 0) {
+        array_def._array_stride = array_type->get_stride_bytes();
+        it = _instructions.insert(it, spv::OpDecorate,
+          {array_type_id, spv::DecorationArrayStride, array_def._array_stride});
+        ++it;
+      }
     }
     }
 
 
     if (const ShaderType::Matrix *matrix_type = base_type->as_matrix()) {
     if (const ShaderType::Matrix *matrix_type = base_type->as_matrix()) {
@@ -1617,6 +1628,10 @@ parse_instruction(const Instruction &op) {
       _defs[op.args[0]]._location = op.args[2];
       _defs[op.args[0]]._location = op.args[2];
       break;
       break;
 
 
+    case spv::DecorationArrayStride:
+      _defs[op.args[0]]._array_stride = op.args[2];
+      break;
+
     default:
     default:
       break;
       break;
     }
     }

+ 1 - 0
panda/src/shaderpipeline/shaderModuleSpirV.h

@@ -147,6 +147,7 @@ public:
     spv::BuiltIn _builtin = spv::BuiltInMax;
     spv::BuiltIn _builtin = spv::BuiltInMax;
     uint32_t _constant = 0;
     uint32_t _constant = 0;
     uint32_t _type_id = 0;
     uint32_t _type_id = 0;
+    uint32_t _array_stride = 0;
     MemberDefinitions _members;
     MemberDefinitions _members;
     bool _used = false;
     bool _used = false;