Browse Source

glgsg: pad SSBOs to 16 byte boundary (required by some drivers)

rdb 7 years ago
parent
commit
b5194d9ff2

+ 2 - 1
panda/src/glstuff/glGraphicsStateGuardian_src.cxx

@@ -6404,7 +6404,8 @@ prepare_shader_buffer(ShaderBuffer *data) {
       _glObjectLabel(GL_SHADER_STORAGE_BUFFER, gbc->_index, name.size(), name.data());
     }
 
-    uint64_t num_bytes = data->get_data_size_bytes();
+    // Some drivers require the buffer to be padded to 16 byte boundary.
+    uint64_t num_bytes = (data->get_data_size_bytes() + 15u) & ~15u;
     if (_supports_buffer_storage) {
       _glBufferStorage(GL_SHADER_STORAGE_BUFFER, num_bytes, data->get_initial_data(), 0);
     } else {

+ 8 - 4
panda/src/gobj/shaderBuffer.I

@@ -19,8 +19,7 @@ INLINE ShaderBuffer::
 ShaderBuffer(const std::string &name, uint64_t size, UsageHint usage_hint) :
   Namable(name),
   _data_size_bytes(size),
-  _usage_hint(usage_hint),
-  _contexts(nullptr) {
+  _usage_hint(usage_hint) {
 }
 
 /**
@@ -32,8 +31,13 @@ ShaderBuffer(const std::string &name, vector_uchar initial_data, UsageHint usage
   Namable(name),
   _data_size_bytes(initial_data.size()),
   _usage_hint(usage_hint),
-  _initial_data(initial_data),
-  _contexts(nullptr) {
+  _initial_data(std::move(initial_data)) {
+
+  // Make sure it is padded to 16 bytes.  Some drivers like that.
+  if ((_initial_data.size() & 15u) != 0) {
+    _initial_data.resize((_initial_data.size() + 15u) & ~15u, 0);
+    _data_size_bytes = _initial_data.size();
+  }
 }
 
 /**

+ 1 - 1
panda/src/gobj/shaderBuffer.cxx

@@ -193,7 +193,7 @@ fillin(DatagramIterator &scan, BamReader *manager) {
 
   if (scan.get_bool() && _data_size_bytes > 0) {
     nassertv_always(_data_size_bytes <= scan.get_remaining_size());
-    _initial_data.resize(_data_size_bytes);
+    _initial_data.resize((_data_size_bytes + 15u) & ~15u);
     scan.extract_bytes(&_initial_data[0], _data_size_bytes);
   } else {
     _initial_data.clear();

+ 1 - 1
panda/src/gobj/shaderBuffer.h

@@ -63,7 +63,7 @@ private:
   vector_uchar _initial_data;
 
   typedef pmap<PreparedGraphicsObjects *, BufferContext *> Contexts;
-  Contexts *_contexts;
+  Contexts *_contexts = nullptr;
 
 public:
   static void register_with_read_factory();