Blender  V2.93
gpu_py_uniformbuffer.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  */
16 
26 #include <Python.h>
27 
28 #include "BLI_string.h"
29 
30 #include "GPU_context.h"
31 #include "GPU_texture.h"
32 #include "GPU_uniform_buffer.h"
33 
34 #include "../generic/py_capi_utils.h"
35 
36 #include "gpu_py.h"
37 #include "gpu_py_buffer.h"
38 
39 #include "gpu_py_uniformbuffer.h" /* own include */
40 
41 /* -------------------------------------------------------------------- */
46 {
47  if (UNLIKELY(bpygpu_ub->ubo == NULL)) {
48  PyErr_SetString(PyExc_ReferenceError,
50  "GPU uniform buffer was freed, no further access is valid");
51 #else
52 
53  "GPU uniform buffer: internal error");
54 #endif
55  return -1;
56  }
57  return 0;
58 }
59 
60 #define BPYGPU_UNIFORMBUF_CHECK_OBJ(bpygpu) \
61  { \
62  if (UNLIKELY(pygpu_uniformbuffer_valid_check(bpygpu) == -1)) { \
63  return NULL; \
64  } \
65  } \
66  ((void)0)
67 
70 /* -------------------------------------------------------------------- */
74 static PyObject *pygpu_uniformbuffer__tp_new(PyTypeObject *UNUSED(self),
75  PyObject *args,
76  PyObject *kwds)
77 {
79 
80  GPUUniformBuf *ubo = NULL;
81  BPyGPUBuffer *pybuffer_obj;
82  char err_out[256] = "unknown error. See console";
83 
84  static const char *_keywords[] = {"data", NULL};
85  static _PyArg_Parser _parser = {"O!:GPUUniformBuf.__new__", _keywords, 0};
86  if (!_PyArg_ParseTupleAndKeywordsFast(args, kwds, &_parser, &BPyGPU_BufferType, &pybuffer_obj)) {
87  return NULL;
88  }
89 
90  if (GPU_context_active_get()) {
92  bpygpu_Buffer_size(pybuffer_obj), pybuffer_obj->buf.as_void, "python_uniformbuffer");
93  }
94  else {
95  STRNCPY(err_out, "No active GPU context found");
96  }
97 
98  if (ubo == NULL) {
99  PyErr_Format(PyExc_RuntimeError, "GPUUniformBuf.__new__(...) failed with '%s'", err_out);
100  return NULL;
101  }
102 
104 }
105 
106 PyDoc_STRVAR(pygpu_uniformbuffer_update_doc,
107  ".. method::update(data)\n"
108  "\n"
109  " Update the data of the uniform buffer object.\n");
110 static PyObject *pygpu_uniformbuffer_update(BPyGPUUniformBuf *self, PyObject *obj)
111 {
113 
114  if (!BPyGPU_Buffer_Check(obj)) {
115  return NULL;
116  }
117 
118  GPU_uniformbuf_update(self->ubo, ((BPyGPUBuffer *)obj)->buf.as_void);
119  Py_RETURN_NONE;
120 }
121 
122 #ifdef BPYGPU_USE_GPUOBJ_FREE_METHOD
123 PyDoc_STRVAR(pygpu_uniformbuffer_free_doc,
124  ".. method::free()\n"
125  "\n"
126  " Free the uniform buffer object.\n"
127  " The uniform buffer object will no longer be accessible.\n");
128 static PyObject *pygpu_uniformbuffer_free(BPyGPUUniformBuf *self)
129 {
131 
133  self->ubo = NULL;
134  Py_RETURN_NONE;
135 }
136 #endif
137 
139 {
140  if (self->ubo) {
142  }
143  Py_TYPE(self)->tp_free((PyObject *)self);
144 }
145 
146 static PyGetSetDef pygpu_uniformbuffer__tp_getseters[] = {
147  {NULL, NULL, NULL, NULL, NULL} /* Sentinel */
148 };
149 
150 static struct PyMethodDef pygpu_uniformbuffer__tp_methods[] = {
151  {"update", (PyCFunction)pygpu_uniformbuffer_update, METH_O, pygpu_uniformbuffer_update_doc},
152 #ifdef BPYGPU_USE_GPUOBJ_FREE_METHOD
153  {"free", (PyCFunction)pygpu_uniformbuffer_free, METH_NOARGS, pygpu_uniformbuffer_free_doc},
154 #endif
155  {NULL, NULL, 0, NULL},
156 };
157 
158 PyDoc_STRVAR(pygpu_uniformbuffer__tp_doc,
159  ".. class:: GPUUniformBuf(data)\n"
160  "\n"
161  " This object gives access to off uniform buffers.\n"
162  "\n"
163  " :arg data: Buffer object.\n"
164  " :type data: :class:`gpu.types.Buffer`\n");
165 PyTypeObject BPyGPUUniformBuf_Type = {
166  PyVarObject_HEAD_INIT(NULL, 0).tp_name = "GPUUniformBuf",
167  .tp_basicsize = sizeof(BPyGPUUniformBuf),
168  .tp_dealloc = (destructor)BPyGPUUniformBuf__tp_dealloc,
169  .tp_flags = Py_TPFLAGS_DEFAULT,
170  .tp_doc = pygpu_uniformbuffer__tp_doc,
171  .tp_methods = pygpu_uniformbuffer__tp_methods,
173  .tp_new = pygpu_uniformbuffer__tp_new,
174 };
175 
178 /* -------------------------------------------------------------------- */
183 {
184  BPyGPUUniformBuf *self;
185 
186  self = PyObject_New(BPyGPUUniformBuf, &BPyGPUUniformBuf_Type);
187  self->ubo = ubo;
188 
189  return (PyObject *)self;
190 }
191 
194 #undef BPYGPU_UNIFORMBUF_CHECK_OBJ
#define STRNCPY(dst, src)
Definition: BLI_string.h:163
#define UNUSED(x)
#define UNLIKELY(x)
GPUContext * GPU_context_active_get(void)
Definition: gpu_context.cc:136
struct GPUUniformBuf GPUUniformBuf
GPUUniformBuf * GPU_uniformbuf_create_ex(size_t size, const void *data, const char *name)
void GPU_uniformbuf_update(GPUUniformBuf *ubo, const void *data)
void GPU_uniformbuf_free(GPUUniformBuf *ubo)
PyObject * self
Definition: bpy_driver.c:185
#define BPYGPU_IS_INIT_OR_ERROR_OBJ
Definition: gpu_py.h:28
PyTypeObject BPyGPU_BufferType
size_t bpygpu_Buffer_size(BPyGPUBuffer *buffer)
#define BPyGPU_Buffer_Check(v)
Definition: gpu_py_buffer.h:25
#define BPYGPU_USE_GPUOBJ_FREE_METHOD
static int pygpu_uniformbuffer_valid_check(BPyGPUUniformBuf *bpygpu_ub)
static PyGetSetDef pygpu_uniformbuffer__tp_getseters[]
static PyObject * pygpu_uniformbuffer__tp_new(PyTypeObject *UNUSED(self), PyObject *args, PyObject *kwds)
#define BPYGPU_UNIFORMBUF_CHECK_OBJ(bpygpu)
PyObject * BPyGPUUniformBuf_CreatePyObject(GPUUniformBuf *ubo)
static void BPyGPUUniformBuf__tp_dealloc(BPyGPUUniformBuf *self)
PyTypeObject BPyGPUUniformBuf_Type
static PyObject * pygpu_uniformbuffer_update(BPyGPUUniformBuf *self, PyObject *obj)
PyDoc_STRVAR(pygpu_uniformbuffer_update_doc, ".. method::update(data)\n" "\n" " Update the data of the uniform buffer object.\n")
static struct PyMethodDef pygpu_uniformbuffer__tp_methods[]
struct BPyGPUUniformBuf BPyGPUUniformBuf
void * as_void
Definition: gpu_py_buffer.h:46
union BPyGPUBuffer::@1119 buf
PyObject_HEAD struct GPUUniformBuf * ubo