32 #include "../generic/py_capi_utils.h"
33 #include "../generic/python_utildefines.h"
42 #define PYGPU_AS_NATIVE_SWITCH(attr) \
43 switch (attr->comp_type) { \
45 PY_AS_NATIVE(int8_t, PyC_Long_AsI8); \
49 PY_AS_NATIVE(uint8_t, PyC_Long_AsU8); \
52 case GPU_COMP_I16: { \
53 PY_AS_NATIVE(int16_t, PyC_Long_AsI16); \
56 case GPU_COMP_U16: { \
57 PY_AS_NATIVE(uint16_t, PyC_Long_AsU16); \
60 case GPU_COMP_I32: { \
61 PY_AS_NATIVE(int32_t, PyC_Long_AsI32); \
64 case GPU_COMP_U32: { \
65 PY_AS_NATIVE(uint32_t, PyC_Long_AsU32); \
68 case GPU_COMP_F32: { \
69 PY_AS_NATIVE(float, PyFloat_AsDouble); \
73 BLI_assert_unreachable(); \
81 #define PY_AS_NATIVE(ty_dst, py_as_native) \
83 ty_dst *data_dst = data_dst_void; \
84 *data_dst = py_as_native(py_src); \
95 PyObject *py_seq_fast,
99 PyObject **value_fast_items = PySequence_Fast_ITEMS(py_seq_fast);
104 #define PY_AS_NATIVE(ty_dst, py_as_native) \
105 ty_dst *data_dst = data_dst_void; \
106 for (uint i = 0; i < len; i++) { \
107 data_dst[i] = py_as_native(value_fast_items[i]); \
116 #undef PYGPU_AS_NATIVE_SWITCH
117 #undef WARN_TYPE_LIMIT_PUSH
118 #undef WARN_TYPE_LIMIT_POP
123 const char *error_prefix)
125 const char *exc_str_size_mismatch =
"Expected a %s of size %d, got %u";
131 if (PyObject_CheckBuffer(seq)) {
134 if (PyObject_GetBuffer(seq, &pybuffer, PyBUF_STRIDES | PyBUF_ND) == -1) {
139 const uint comp_len = pybuffer.ndim == 1 ? 1 : (
uint)pybuffer.shape[1];
141 if (pybuffer.shape[0] != vert_len) {
143 PyExc_ValueError, exc_str_size_mismatch,
"sequence", vert_len, pybuffer.shape[0]);
146 else if (comp_len != attr->
comp_len) {
147 PyErr_Format(PyExc_ValueError, exc_str_size_mismatch,
"component", attr->
comp_len, comp_len);
154 PyBuffer_Release(&pybuffer);
160 PyObject *seq_fast = PySequence_Fast(seq,
"Vertex buffer fill");
161 if (seq_fast ==
NULL) {
165 const uint seq_len = PySequence_Fast_GET_SIZE(seq_fast);
167 if (seq_len != vert_len) {
168 PyErr_Format(PyExc_ValueError, exc_str_size_mismatch,
"sequence", vert_len, seq_len);
171 PyObject **seq_items = PySequence_Fast_ITEMS(seq_fast);
174 for (
uint i = 0; i < seq_len; i++) {
176 PyObject *item = seq_items[i];
181 for (
uint i = 0; i < seq_len; i++) {
183 PyObject *seq_fast_item = PySequence_Fast(seq_items[i], error_prefix);
185 if (seq_fast_item ==
NULL) {
189 if (PySequence_Fast_GET_SIZE(seq_fast_item) != attr->
comp_len) {
190 PyErr_Format(PyExc_ValueError,
191 exc_str_size_mismatch,
194 PySequence_Fast_GET_SIZE(seq_fast_item));
196 Py_DECREF(seq_fast_item);
202 Py_DECREF(seq_fast_item);
206 if (PyErr_Occurred()) {
219 PyObject *py_seq_data,
220 const char *error_prefix)
223 PyErr_Format(PyExc_ValueError,
"Format id %d out of range",
id);
228 PyErr_SetString(PyExc_ValueError,
"Can't fill, static buffer already in use");
252 static const char *_keywords[] = {
"format",
"len",
NULL};
253 static _PyArg_Parser _parser = {
"O!I:GPUVertBuf.__new__", _keywords, 0};
254 if (!_PyArg_ParseTupleAndKeywordsFast(
268 ".. method:: attr_fill(id, data)\n"
270 " Insert data into the buffer for a single attribute.\n"
272 " :param id: Either the name or the id of the attribute.\n"
273 " :type id: int or str\n"
274 " :param data: Sequence of data that should be stored in the buffer\n"
275 " :type data: sequence of floats, ints, vectors or matrices\n");
279 PyObject *identifier;
281 static const char *_keywords[] = {
"id",
"data",
NULL};
282 static _PyArg_Parser _parser = {
"OO:attr_fill", _keywords, 0};
283 if (!_PyArg_ParseTupleAndKeywordsFast(args, kwds, &_parser, &identifier, &
data)) {
289 if (PyLong_Check(identifier)) {
290 id = PyLong_AsLong(identifier);
292 else if (PyUnicode_Check(identifier)) {
294 const char *name = PyUnicode_AsUTF8(identifier);
297 PyErr_SetString(PyExc_ValueError,
"Unknown attribute name");
302 PyErr_SetString(PyExc_TypeError,
"expected int or str type as identifier");
316 METH_VARARGS | METH_KEYWORDS,
317 pygpu_vertbuf_attr_fill_doc},
324 Py_TYPE(
self)->tp_free(
self);
328 ".. class:: GPUVertBuf(len, format)\n"
332 " :param len: Amount of vertices that will fit into this buffer.\n"
333 " :type type: `int`\n"
334 " :param format: Vertex format.\n"
335 " :type buf: :class:`gpu.types.GPUVertFormat`\n");
337 PyVarObject_HEAD_INIT(
NULL, 0).tp_name =
"GPUVertBuf",
340 .tp_flags = Py_TPFLAGS_DEFAULT,
341 .tp_doc = pygpu_vertbuf__tp_doc,
359 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