gpy.types.GPUUniformBuf: support any object exposing buffer interface

Since uniform buffers are generally structs and not sequences,
`BPyGPU_BufferType` objects are not suitable for filling the buffer.
This commit is contained in:
Germano Cavalcante 2022-04-12 22:44:57 -03:00
parent 132576ebb1
commit af17676005
1 changed files with 19 additions and 10 deletions

View File

@ -64,17 +64,17 @@ static PyObject *pygpu_uniformbuffer__tp_new(PyTypeObject *UNUSED(self),
BPYGPU_IS_INIT_OR_ERROR_OBJ;
GPUUniformBuf *ubo = NULL;
BPyGPUBuffer *pybuffer_obj;
PyObject *pybuffer_obj;
char err_out[256] = "unknown error. See console";
static const char *_keywords[] = {"data", NULL};
static _PyArg_Parser _parser = {
"O!" /* `data` */
"O" /* `data` */
":GPUUniformBuf.__new__",
_keywords,
0,
};
if (!_PyArg_ParseTupleAndKeywordsFast(args, kwds, &_parser, &BPyGPU_BufferType, &pybuffer_obj)) {
if (!_PyArg_ParseTupleAndKeywordsFast(args, kwds, &_parser, &pybuffer_obj)) {
return NULL;
}
@ -82,13 +82,19 @@ static PyObject *pygpu_uniformbuffer__tp_new(PyTypeObject *UNUSED(self),
STRNCPY(err_out, "No active GPU context found");
}
else {
size_t size = bpygpu_Buffer_size(pybuffer_obj);
if ((size % 16) != 0) {
Py_buffer pybuffer;
if (PyObject_GetBuffer(pybuffer_obj, &pybuffer, PyBUF_SIMPLE) == -1) {
/* PyObject_GetBuffer raise a PyExc_BufferError */
return NULL;
}
if ((pybuffer.len % 16) != 0) {
STRNCPY(err_out, "UBO is not padded to size of vec4");
}
else {
ubo = GPU_uniformbuf_create_ex(size, pybuffer_obj->buf.as_void, "python_uniformbuffer");
ubo = GPU_uniformbuf_create_ex(pybuffer.len, pybuffer.buf, "python_uniformbuffer");
}
PyBuffer_Release(&pybuffer);
}
if (ubo == NULL) {
@ -107,11 +113,14 @@ static PyObject *pygpu_uniformbuffer_update(BPyGPUUniformBuf *self, PyObject *ob
{
BPYGPU_UNIFORMBUF_CHECK_OBJ(self);
if (!BPyGPU_Buffer_Check(obj)) {
Py_buffer pybuffer;
if (PyObject_GetBuffer(obj, &pybuffer, PyBUF_SIMPLE) == -1) {
/* PyObject_GetBuffer raise a PyExc_BufferError */
return NULL;
}
GPU_uniformbuf_update(self->ubo, ((BPyGPUBuffer *)obj)->buf.as_void);
GPU_uniformbuf_update(self->ubo, pybuffer.buf);
PyBuffer_Release(&pybuffer);
Py_RETURN_NONE;
}
@ -156,8 +165,8 @@ PyDoc_STRVAR(pygpu_uniformbuffer__tp_doc,
"\n"
" This object gives access to off uniform buffers.\n"
"\n"
" :arg data: Buffer object.\n"
" :type data: :class:`gpu.types.Buffer`\n");
" :arg data: Data to fill the buffer.\n"
" :type data: object exposing buffer interface\n");
PyTypeObject BPyGPUUniformBuf_Type = {
PyVarObject_HEAD_INIT(NULL, 0).tp_name = "GPUUniformBuf",
.tp_basicsize = sizeof(BPyGPUUniformBuf),