18 #include "../generic/py_capi_utils.h"
19 #include "../generic/python_utildefines.h"
28 #define PYGPU_AS_NATIVE_SWITCH(attr) \
29 switch (attr->comp_type) { \
31 PY_AS_NATIVE(int8_t, PyC_Long_AsI8); \
35 PY_AS_NATIVE(uint8_t, PyC_Long_AsU8); \
38 case GPU_COMP_I16: { \
39 PY_AS_NATIVE(int16_t, PyC_Long_AsI16); \
42 case GPU_COMP_U16: { \
43 PY_AS_NATIVE(uint16_t, PyC_Long_AsU16); \
46 case GPU_COMP_I32: { \
47 PY_AS_NATIVE(int32_t, PyC_Long_AsI32); \
50 case GPU_COMP_U32: { \
51 PY_AS_NATIVE(uint32_t, PyC_Long_AsU32); \
54 case GPU_COMP_F32: { \
55 PY_AS_NATIVE(float, PyFloat_AsDouble); \
59 BLI_assert_unreachable(); \
67 #define PY_AS_NATIVE(ty_dst, py_as_native) \
69 ty_dst *data_dst = data_dst_void; \
70 *data_dst = py_as_native(py_src); \
81 PyObject *py_seq_fast,
85 PyObject **value_fast_items = PySequence_Fast_ITEMS(py_seq_fast);
90 #define PY_AS_NATIVE(ty_dst, py_as_native) \
91 ty_dst *data_dst = data_dst_void; \
92 for (uint i = 0; i < len; i++) { \
93 data_dst[i] = py_as_native(value_fast_items[i]); \
102 #undef PYGPU_AS_NATIVE_SWITCH
103 #undef WARN_TYPE_LIMIT_PUSH
104 #undef WARN_TYPE_LIMIT_POP
109 const char *error_prefix)
111 const char *exc_str_size_mismatch =
"Expected a %s of size %d, got %u";
117 if (PyObject_CheckBuffer(seq)) {
120 if (PyObject_GetBuffer(seq, &pybuffer, PyBUF_STRIDES | PyBUF_ND) == -1) {
125 const uint comp_len = pybuffer.ndim == 1 ? 1 : (
uint)pybuffer.shape[1];
127 if (pybuffer.shape[0] != vert_len) {
129 PyExc_ValueError, exc_str_size_mismatch,
"sequence", vert_len, pybuffer.shape[0]);
132 else if (comp_len != attr->
comp_len) {
133 PyErr_Format(PyExc_ValueError, exc_str_size_mismatch,
"component", attr->
comp_len, comp_len);
140 PyBuffer_Release(&pybuffer);
146 PyObject *seq_fast = PySequence_Fast(seq,
"Vertex buffer fill");
147 if (seq_fast ==
NULL) {
151 const uint seq_len = PySequence_Fast_GET_SIZE(seq_fast);
153 if (seq_len != vert_len) {
154 PyErr_Format(PyExc_ValueError, exc_str_size_mismatch,
"sequence", vert_len, seq_len);
157 PyObject **seq_items = PySequence_Fast_ITEMS(seq_fast);
160 for (
uint i = 0; i < seq_len; i++) {
162 PyObject *item = seq_items[i];
167 for (
uint i = 0; i < seq_len; i++) {
169 PyObject *seq_fast_item = PySequence_Fast(seq_items[i], error_prefix);
171 if (seq_fast_item ==
NULL) {
175 if (PySequence_Fast_GET_SIZE(seq_fast_item) != attr->
comp_len) {
176 PyErr_Format(PyExc_ValueError,
177 exc_str_size_mismatch,
180 PySequence_Fast_GET_SIZE(seq_fast_item));
182 Py_DECREF(seq_fast_item);
188 Py_DECREF(seq_fast_item);
192 if (PyErr_Occurred()) {
205 PyObject *py_seq_data,
206 const char *error_prefix)
209 PyErr_Format(PyExc_ValueError,
"Format id %d out of range",
id);
214 PyErr_SetString(PyExc_ValueError,
"Can't fill, static buffer already in use");
238 static const char *_keywords[] = {
"format",
"len",
NULL};
239 static _PyArg_Parser _parser = {
242 ":GPUVertBuf.__new__",
246 if (!_PyArg_ParseTupleAndKeywordsFast(
260 ".. method:: attr_fill(id, data)\n"
262 " Insert data into the buffer for a single attribute.\n"
264 " :param id: Either the name or the id of the attribute.\n"
265 " :type id: int or str\n"
266 " :param data: Sequence of data that should be stored in the buffer\n"
267 " :type data: sequence of floats, ints, vectors or matrices\n");
271 PyObject *identifier;
273 static const char *_keywords[] = {
"id",
"data",
NULL};
274 static _PyArg_Parser _parser = {
281 if (!_PyArg_ParseTupleAndKeywordsFast(args, kwds, &_parser, &identifier, &
data)) {
287 if (PyLong_Check(identifier)) {
288 id = PyLong_AsLong(identifier);
290 else if (PyUnicode_Check(identifier)) {
292 const char *name = PyUnicode_AsUTF8(identifier);
295 PyErr_SetString(PyExc_ValueError,
"Unknown attribute name");
300 PyErr_SetString(PyExc_TypeError,
"expected int or str type as identifier");
314 METH_VARARGS | METH_KEYWORDS,
315 pygpu_vertbuf_attr_fill_doc},
322 Py_TYPE(
self)->tp_free(
self);
326 ".. class:: GPUVertBuf(format, len)\n"
330 " :param format: Vertex format.\n"
331 " :type buf: :class:`gpu.types.GPUVertFormat`\n"
332 " :param len: Amount of vertices that will fit into this buffer.\n"
333 " :type type: `int`\n");
335 PyVarObject_HEAD_INIT(
NULL, 0).tp_name =
"GPUVertBuf",
338 .tp_flags = Py_TPFLAGS_DEFAULT,
339 .tp_doc = pygpu_vertbuf__tp_doc,
357 return (PyObject *)
self;
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
const GPUVertFormat * GPU_vertbuf_get_format(const GPUVertBuf *verts)
uint GPU_vertbuf_get_vertex_len(const GPUVertBuf *verts)
#define GPU_vertbuf_create_with_format(format)
void GPU_vertbuf_discard(GPUVertBuf *)
struct GPUVertBuf GPUVertBuf
void GPU_vertbuf_data_alloc(GPUVertBuf *, uint v_len)
void GPU_vertbuf_attr_fill_stride(GPUVertBuf *, uint a_idx, uint stride, const void *data)
void * GPU_vertbuf_get_data(const GPUVertBuf *verts)
GPU_INLINE void * GPU_vertbuf_raw_step(GPUVertBufRaw *a)
void GPU_vertbuf_attr_get_raw_data(GPUVertBuf *, uint a_idx, GPUVertBufRaw *access)
Read Guarded memory(de)allocation.
PyTypeObject BPyGPUVertBuf_Type
static PyObject * pygpu_vertbuf__tp_new(PyTypeObject *UNUSED(type), PyObject *args, PyObject *kwds)
static int pygpu_vertbuf_fill(GPUVertBuf *buf, int id, PyObject *py_seq_data, const char *error_prefix)
static struct PyMethodDef pygpu_vertbuf__tp_methods[]
PyObject * BPyGPUVertBuf_CreatePyObject(GPUVertBuf *buf)
#define PYGPU_AS_NATIVE_SWITCH(attr)
static void pygpu_fill_format_sequence(void *data_dst_void, PyObject *py_seq_fast, const GPUVertAttr *attr)
static PyObject * pygpu_vertbuf_attr_fill(BPyGPUVertBuf *self, PyObject *args, PyObject *kwds)
static void pygpu_fill_format_elem(void *data_dst_void, PyObject *py_src, const GPUVertAttr *attr)
PyDoc_STRVAR(pygpu_vertbuf_attr_fill_doc, ".. method:: attr_fill(id, data)\n" "\n" " Insert data into the buffer for a single attribute.\n" "\n" " :param id: Either the name or the id of the attribute.\n" " :type id: int or str\n" " :param data: Sequence of data that should be stored in the buffer\n" " :type data: sequence of floats, ints, vectors or matrices\n")
static void pygpu_vertbuf__tp_dealloc(BPyGPUVertBuf *self)
static bool pygpu_vertbuf_fill_impl(GPUVertBuf *vbo, uint data_id, PyObject *seq, const char *error_prefix)
struct BPyGPUVertBuf BPyGPUVertBuf