Forráskód Böngészése

shaderpipeline: Retain array stride from SPIR-V

rdb 1 hete
szülő
commit
2889cc8a7b

+ 11 - 2
panda/src/gobj/shaderType.I

@@ -171,9 +171,10 @@ has_member(const std::string &name) const {
  * Constructs an array type from a base type and number of elements.
  */
 INLINE ShaderType::Array::
-Array(const ShaderType *element_type, uint32_t num_elements) :
+Array(const ShaderType *element_type, uint32_t num_elements, uint32_t stride_bytes) :
   _element_type(element_type),
-  _num_elements(num_elements) {
+  _num_elements(num_elements),
+  _stride_bytes(stride_bytes) {
 }
 
 /**
@@ -192,6 +193,14 @@ get_num_elements() const {
   return _num_elements;
 }
 
+/**
+ * Returns the array stride in bytes, or 0 if this was not specified.
+ */
+INLINE uint32_t ShaderType::Array::
+get_stride_bytes() const {
+  return _stride_bytes;
+}
+
 /**
  * Constructs an image type.
  */

+ 17 - 13
panda/src/gobj/shaderType.cxx

@@ -1090,21 +1090,13 @@ compare_to_impl(const ShaderType &other) const {
   if (_element_type != other_array._element_type) {
     return _element_type < other_array._element_type ? -1 : 1;
   }
+  if (_stride_bytes != other_array._stride_bytes) {
+    return _stride_bytes < other_array._stride_bytes ? -1 : 1;
+  }
   return (_num_elements > other_array._num_elements)
        - (_num_elements < other_array._num_elements);
 }
 
-/**
- * Returns the array stride in bytes.
- */
-uint32_t ShaderType::Array::
-get_stride_bytes() const {
-  // Array stride is always (at least) 16 bytes in std140 / DX9, even though
-  // this is (indeed) incredibly wasteful for arrays of scalars.
-  uint32_t size = _element_type->get_size_bytes();
-  return (size + 15) & ~15;
-}
-
 /**
  * Returns the alignment in bytes of this type in memory, if applicable.
  */
@@ -1123,7 +1115,14 @@ get_size_bytes() const {
   // Arrays have padding at the end so that the next member is aligned to a
   // 16-byte boundary.  This implies that a float may directly follow a vec3,
   // but not a vec3[1]!  I didn't make up these rules.
-  return get_stride_bytes() * _num_elements;
+  uint32_t stride_bytes = _stride_bytes;
+  if (stride_bytes == 0) {
+    // Array stride is always (at least) 16 bytes in std140 / DX9, even though
+    // this is (indeed) incredibly wasteful for arrays of scalars.
+    uint32_t size = _element_type->get_size_bytes();
+    stride_bytes = (size + 15) & ~15;
+  }
+  return stride_bytes * _num_elements;
 }
 
 /**
@@ -1151,6 +1150,7 @@ void ShaderType::Array::
 write_datagram(BamWriter *manager, Datagram &dg) {
   manager->write_pointer(dg, _element_type);
   dg.add_uint32(_num_elements);
+  dg.add_uint32(_stride_bytes);
 }
 
 /**
@@ -1179,7 +1179,11 @@ make_from_bam(const FactoryParams &params) {
 
   manager->read_pointer(scan);
   uint32_t num_elements = scan.get_uint32();
-  ShaderType *type = new ShaderType::Array(nullptr, num_elements);
+  uint32_t stride_bytes = 0;
+  if (scan.get_remaining_size() >= 4) {
+    stride_bytes = scan.get_uint32();
+  }
+  ShaderType *type = new ShaderType::Array(nullptr, num_elements, stride_bytes);
 
   manager->register_change_this(change_this, type);
   return type;

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

@@ -393,10 +393,12 @@ private:
  */
 class EXPCL_PANDA_GOBJ ShaderType::Array final : public ShaderType {
 public:
-  INLINE Array(const ShaderType *element_type, uint32_t num_elements);
+  INLINE Array(const ShaderType *element_type, uint32_t num_elements,
+               uint32_t stride_bytes = 0);
 
   INLINE const ShaderType *get_element_type() const;
   INLINE uint32_t get_num_elements() const;
+  INLINE uint32_t get_stride_bytes() const;
 
   virtual bool unwrap_array(const ShaderType *&element_type, uint32_t &num_elements) const override;
 
@@ -412,7 +414,6 @@ public:
   virtual void output_signature(std::ostream &out) const override;
   virtual int compare_to_impl(const ShaderType &other) const override;
 
-  uint32_t get_stride_bytes() const;
   virtual uint32_t get_align_bytes() const override;
   virtual uint32_t get_size_bytes() const override;
   virtual int get_num_interface_locations() const override;
@@ -424,10 +425,12 @@ public:
 PUBLISHED:
   MAKE_PROPERTY(element_type, get_element_type);
   MAKE_PROPERTY(num_elements, get_num_elements);
+  MAKE_PROPERTY(stride_bytes, get_stride_bytes);
 
 private:
   const ShaderType *_element_type;
   uint32_t _num_elements;
+  uint32_t _stride_bytes = 0;
 
 protected:
   virtual void write_datagram(BamWriter *manager, Datagram &dg) override;

+ 2 - 2
panda/src/shaderpipeline/spirVResultDatabase.cxx

@@ -403,7 +403,7 @@ parse_instruction(spv::Op opcode, const uint32_t *args, uint32_t nargs, uint32_t
   case spv::OpTypeArray:
     if (_defs[args[1]]._type != nullptr) {
       record_type(args[0], ShaderType::register_type(
-        ShaderType::Array(_defs[args[1]]._type, _defs[args[2]]._constant)));
+        ShaderType::Array(_defs[args[1]]._type, _defs[args[2]]._constant, _defs[args[0]]._array_stride)));
     }
     _defs[args[0]]._type_id = args[1];
     break;
@@ -411,7 +411,7 @@ parse_instruction(spv::Op opcode, const uint32_t *args, uint32_t nargs, uint32_t
   case spv::OpTypeRuntimeArray:
     if (_defs[args[1]]._type != nullptr) {
       record_type(args[0], ShaderType::register_type(
-        ShaderType::Array(_defs[args[1]]._type, 0)));
+        ShaderType::Array(_defs[args[1]]._type, 0, _defs[args[0]]._array_stride)));
     }
     _defs[args[0]]._type_id = args[1];
     break;