[Bf-blender-cvs] [fe5455b75e1] pygpu_extensions: GPU Python: Implement new object type 'gpu.types.GPUUniformBuf'

Germano Cavalcante noreply at git.blender.org
Thu Feb 11 19:03:05 CET 2021


Commit: fe5455b75e1c0151635b92fbe41979ac467581b6
Author: Germano Cavalcante
Date:   Thu Feb 11 14:54:46 2021 -0300
Branches: pygpu_extensions
https://developer.blender.org/rBfe5455b75e1c0151635b92fbe41979ac467581b6

GPU Python: Implement new object type 'gpu.types.GPUUniformBuf'

For use by `gpu.types.GPUShader` only.

The API of this object includes:
```
>>> gpu.types.GPUUniformBuf.
                            free(
                            update(
```

===================================================================

M	source/blender/python/gpu/CMakeLists.txt
M	source/blender/python/gpu/gpu_py_shader.c
M	source/blender/python/gpu/gpu_py_types.c
M	source/blender/python/gpu/gpu_py_types.h
A	source/blender/python/gpu/gpu_py_uniformbuffer.c
A	source/blender/python/gpu/gpu_py_uniformbuffer.h

===================================================================

diff --git a/source/blender/python/gpu/CMakeLists.txt b/source/blender/python/gpu/CMakeLists.txt
index ba3561c0293..fe5c559fcc0 100644
--- a/source/blender/python/gpu/CMakeLists.txt
+++ b/source/blender/python/gpu/CMakeLists.txt
@@ -46,6 +46,7 @@ set(SRC
   gpu_py_state.c
   gpu_py_texture.c
   gpu_py_types.c
+  gpu_py_uniformbuffer.c
   gpu_py_vertex_buffer.c
   gpu_py_vertex_format.c
 
@@ -62,6 +63,7 @@ set(SRC
   gpu_py_state.h
   gpu_py_texture.h
   gpu_py_types.h
+  gpu_py_uniformbuffer.h
   gpu_py_vertex_buffer.h
   gpu_py_vertex_format.h
 )
diff --git a/source/blender/python/gpu/gpu_py_shader.c b/source/blender/python/gpu/gpu_py_shader.c
index a099bee4dea..0440aa8b273 100644
--- a/source/blender/python/gpu/gpu_py_shader.c
+++ b/source/blender/python/gpu/gpu_py_shader.c
@@ -27,6 +27,7 @@
 
 #include "GPU_shader.h"
 #include "GPU_texture.h"
+#include "GPU_uniform_buffer.h"
 
 #include "../generic/py_capi_utils.h"
 #include "../generic/python_utildefines.h"
@@ -34,6 +35,7 @@
 
 #include "gpu_py_api.h"
 #include "gpu_py_texture.h"
+#include "gpu_py_uniformbuffer.h"
 #include "gpu_py_vertex_format.h"
 
 #include "gpu_py_shader.h" /* own include */
@@ -486,6 +488,32 @@ static PyObject *py_shader_uniform_texture(BPyGPUShader *self, PyObject *args)
   Py_RETURN_NONE;
 }
 
+PyDoc_STRVAR(
+    py_shader_uniform_buffer_doc,
+    ".. method:: uniform_buffer(name, ubo)\n"
+    "\n"
+    "   Specify the value of an uniform buffer object variable for the current GPUShader.\n"
+    "\n"
+    "   :param name: name of the uniform variable whose UBO is to be specified.\n"
+    "   :type name: str\n"
+    "   :param ubo: Uniform Buffer to attach.\n"
+    "   :type texture: :class:`gpu.types.GPUUniformBuf`\n");
+static PyObject *py_shader_uniform_buffer(BPyGPUShader *self, PyObject *args)
+{
+  const char *name;
+  BPyGPUUniformBuf *py_ubo;
+  if (!PyArg_ParseTuple(
+          args, "sO!:GPUShader.uniform_buffer", &name, &BPyGPUUniformBuf_Type, &py_ubo)) {
+    return NULL;
+  }
+
+  int slot = GPU_shader_get_uniform_block(self->shader, name);
+  GPU_uniformbuf_bind(py_ubo->ubo, slot);
+  GPU_shader_uniform_1i(self->shader, name, slot);
+
+  Py_RETURN_NONE;
+}
+
 PyDoc_STRVAR(
     py_shader_attr_from_name_doc,
     ".. method:: attr_from_name(name)\n"
@@ -558,6 +586,10 @@ static struct PyMethodDef py_shader_methods[] = {
      (PyCFunction)py_shader_uniform_texture,
      METH_VARARGS,
      py_shader_uniform_texture_doc},
+    {"uniform_buffer",
+     (PyCFunction)py_shader_uniform_buffer,
+     METH_VARARGS,
+     py_shader_uniform_buffer_doc},
     {"attr_from_name",
      (PyCFunction)py_shader_attr_from_name,
      METH_O,
diff --git a/source/blender/python/gpu/gpu_py_types.c b/source/blender/python/gpu/gpu_py_types.c
index aab7aaf666c..64a42ad910f 100644
--- a/source/blender/python/gpu/gpu_py_types.c
+++ b/source/blender/python/gpu/gpu_py_types.c
@@ -70,6 +70,9 @@ PyObject *bpygpu_types_init(void)
   if (PyType_Ready(&BPyGPUFrameBuffer_Type) < 0) {
     return NULL;
   }
+  if (PyType_Ready(&BPyGPUUniformBuf_Type) < 0) {
+    return NULL;
+  }
 
 #define MODULE_TYPE_ADD(s, t) \
   PyModule_AddObject(s, t.tp_name, (PyObject *)&t); \
@@ -84,6 +87,7 @@ PyObject *bpygpu_types_init(void)
   MODULE_TYPE_ADD(submodule, BPyGPUShader_Type);
   MODULE_TYPE_ADD(submodule, BPyGPUTexture_Type);
   MODULE_TYPE_ADD(submodule, BPyGPUFrameBuffer_Type);
+  MODULE_TYPE_ADD(submodule, BPyGPUUniformBuf_Type);
 
 #undef MODULE_TYPE_ADD
 
diff --git a/source/blender/python/gpu/gpu_py_types.h b/source/blender/python/gpu/gpu_py_types.h
index ae44ec32f14..eb72c04d53e 100644
--- a/source/blender/python/gpu/gpu_py_types.h
+++ b/source/blender/python/gpu/gpu_py_types.h
@@ -28,6 +28,7 @@
 #include "gpu_py_offscreen.h"
 #include "gpu_py_shader.h"
 #include "gpu_py_texture.h"
+#include "gpu_py_uniformbuffer.h"
 #include "gpu_py_vertex_buffer.h"
 #include "gpu_py_vertex_format.h"
 
diff --git a/source/blender/python/gpu/gpu_py_uniformbuffer.c b/source/blender/python/gpu/gpu_py_uniformbuffer.c
new file mode 100644
index 00000000000..40951ef4ef4
--- /dev/null
+++ b/source/blender/python/gpu/gpu_py_uniformbuffer.c
@@ -0,0 +1,182 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/** \file
+ * \ingroup bpygpu
+ *
+ * This file defines the uniform buffer functionalities of the 'gpu' module
+ *
+ * - Use ``bpygpu_`` for local API.
+ * - Use ``BPyGPU`` for public API.
+ */
+
+#include <Python.h>
+
+#include "GPU_context.h"
+#include "GPU_texture.h"
+#include "GPU_uniform_buffer.h"
+
+#include "../generic/py_capi_utils.h"
+
+#include "gpu_py.h"
+#include "gpu_py_api.h"
+#include "gpu_py_buffer.h"
+
+#include "gpu_py_uniformbuffer.h" /* own include */
+
+/* -------------------------------------------------------------------- */
+/** \name GPUUniformBuf Common Utilities
+ * \{ */
+
+static int py_uniformbuffer_valid_check(BPyGPUUniformBuf *bpygpu_ub)
+{
+  if (UNLIKELY(bpygpu_ub->ubo == NULL)) {
+    PyErr_SetString(PyExc_ReferenceError,
+                    "GPU uniform buffer was freed, no further access is valid");
+    return -1;
+  }
+  return 0;
+}
+
+#define PY_UNIFORMBUF_CHECK_OBJ(bpygpu) \
+  { \
+    if (UNLIKELY(py_uniformbuffer_valid_check(bpygpu) == -1)) { \
+      return NULL; \
+    } \
+  } \
+  ((void)0)
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name GPUUniformBuf Type
+ * \{ */
+
+static PyObject *py_uniformbuffer_new(PyTypeObject *UNUSED(self), PyObject *args, PyObject *kwds)
+{
+  BPYGPU_IS_INIT_OR_ERROR_OBJ;
+
+  GPUUniformBuf *ubo = NULL;
+  PyBuffer *pybuffer_obj;
+  char err_out[256] = "unknown error. See console";
+
+  static const char *_keywords[] = {"data", NULL};
+  static _PyArg_Parser _parser = {"O!:GPUUniformBuf.__new__", _keywords, 0};
+  if (!_PyArg_ParseTupleAndKeywordsFast(args, kwds, &_parser, &BPyGPU_BufferType, &pybuffer_obj)) {
+    return NULL;
+  }
+
+  if (GPU_context_active_get()) {
+    ubo = GPU_uniformbuf_create_ex(
+        bpygpu_Buffer_size(pybuffer_obj), pybuffer_obj->buf.asvoid, "python_uniformbuffer");
+  }
+  else {
+    strncpy(err_out, "No active GPU context found", 256);
+  }
+
+  if (ubo == NULL) {
+    PyErr_Format(PyExc_RuntimeError, "GPUUniformBuf.__new__(...) failed with '%s'", err_out);
+    return NULL;
+  }
+
+  return BPyGPUUniformBuf_CreatePyObject(ubo);
+}
+
+PyDoc_STRVAR(py_uniformbuffer_update_doc,
+             ".. method::update(data)\n"
+             "\n"
+             "   Update the data of the uniform buffer object.\n");
+static PyObject *py_uniformbuffer_update(BPyGPUUniformBuf *self, PyObject *obj)
+{
+  PY_UNIFORMBUF_CHECK_OBJ(self);
+
+  if (!BPyGPU_Buffer_Check(obj)) {
+    return NULL;
+  }
+
+  GPU_uniformbuf_update(self->ubo, ((PyBuffer *)obj)->buf.asvoid);
+  Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(py_uniformbuffer_free_doc,
+             ".. method::free()\n"
+             "\n"
+             "   Free the uniform buffer object.\n"
+             "   The uniform buffer object will no longer be accessible.\n");
+static PyObject *py_uniformbuffer_free(BPyGPUUniformBuf *self)
+{
+  PY_UNIFORMBUF_CHECK_OBJ(self);
+
+  GPU_uniformbuf_free(self->ubo);
+  self->ubo = NULL;
+  Py_RETURN_NONE;
+}
+
+static void BPyGPUUniformBuf__tp_dealloc(BPyGPUUniformBuf *self)
+{
+  if (self->ubo) {
+    GPU_uniformbuf_free(self->ubo);
+  }
+  Py_TYPE(self)->tp_free((PyObject *)self);
+}
+
+static PyGetSetDef py_uniformbuffer_getseters[] = {
+    {NULL, NULL, NULL, NULL, NULL} /* Sentinel */
+};
+
+static struct PyMethodDef py_uniformbuffer_methods[] = {
+    {"update", (PyCFunction)py_uniformbuffer_update, METH_O, py_uniformbuffer_update_doc},
+    {"free", (PyCFunction)py_uniformbuffer_free, METH_NOARGS, py_uniformbuffer_free_doc},
+    {NULL, NULL, 0, NULL},
+};
+
+PyDoc_STRVAR(py_uniformbuffer_doc,
+             ".. class:: GPUUniformBuf(data)\n"
+             "\n"
+             "   This object gives access to off uniform buffers.\n"
+             "\n"
+             "   :arg data: Buffer object.\n"
+             "   :type data: `Buffer`\n");
+PyTypeObject BPyGPUUniformBuf_Type = {
+    PyVarObject_HEAD_INIT(NULL, 0).tp_name = "GPUUniformBuf",
+    .tp_basicsize = sizeof(BPyGPUUniformBuf),
+    .tp_dealloc = (destructor)BPyGPUUniformBuf__tp_dealloc,
+    .tp_flags = Py_TPFLAGS_DEFAULT,
+    .tp_doc = py_uniformbuffer_doc,
+    .tp_methods = py_uniformbuffer_methods,
+    .tp_getset = py_uniformbuffer_getseters,
+    .tp_new = py_uniformbuffer_new,
+};
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Public API
+ * \{ */
+
+PyObject *BPyGPUUniformBuf_CreatePyObject(GPUUniformBuf *ubo)
+{
+  BPyGPUUniformBuf *self;
+
+  self = PyObject_New(BPyGPUUniformBuf, &BPyGPUUniformBuf_Type);
+  self->ubo = ubo;
+
+  return (PyObject *)self;
+}
+
+/** \} */
+
+#undef PY_UNIFORMBUF_CHECK_OBJ
diff --git a/source/blender/python/gpu/gpu_py_types.h b/source/blender/python/gpu/gpu_py_uniformbuffer.h
similarity index 69%
copy from source/blender/python/gpu/gpu_py_types.h
copy to source/blender/python/gpu/gpu_py_uniformbuffer.h
index ae44ec32f14..a13c33ae78a 100644
--- a/source/blender/python/gpu/gpu_py_types.h
+++ b/source/blender/python/gpu/gpu_py_uniformbuffer.h
@@ -20,15 +20,14 @@
 
 #pragma once
 
-#include "gpu_py_buffer.h"
+#include "BLI_compiler_attrs.h"
 
-#include "gpu_py_batch.h"
-#include "gpu_py_element.h"
-#include "gpu_py_framebuffer.h"
-#include "gpu_py_offscreen.h"
-#include "gpu_py_shader.h"
-#include "gpu_py_texture.h"
-#include "gpu_py_vertex_buffer.h

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list