37 #include "../generic/py_capi_utils.h"
99 PyErr_SetString(PyExc_ReferenceError,
101 "GPU texture was freed, no further access is valid"
103 "GPU texture: internal error"
112 #define BPYGPU_TEXTURE_CHECK_OBJ(bpygpu) \
114 if (UNLIKELY(pygpu_texture_valid_check(bpygpu) == -1)) { \
131 int size[3] = {1, 1, 1};
133 int is_cubemap =
false;
136 char err_out[256] =
"unknown error. See console";
138 static const char *_keywords[] = {
"size",
"layers",
"is_cubemap",
"format",
"data",
NULL};
139 static _PyArg_Parser _parser = {
"O|$ipO&O!:GPUTexture.__new__", _keywords, 0};
140 if (!_PyArg_ParseTupleAndKeywordsFast(args,
147 &pygpu_textureformat,
154 if (PySequence_Check(py_size)) {
155 len = PySequence_Size(py_size);
156 if ((
len < 1) || (
len > 3)) {
157 PyErr_Format(PyExc_ValueError,
158 "GPUTexture.__new__: \"size\" must be between 1 and 3 in length (got %d)",
162 if (
PyC_AsArray(
size, py_size,
len, &PyLong_Type,
false,
"GPUTexture.__new__") == -1) {
166 else if (PyLong_Check(py_size)) {
167 size[0] = PyLong_AsLong(py_size);
170 PyErr_SetString(PyExc_ValueError,
"GPUTexture.__new__: Expected an int or tuple as first arg");
177 PyErr_SetString(PyExc_ValueError,
178 "GPUTexture.__new__: Only Buffer of format `FLOAT` is currently supported");
183 int component_size_expected =
sizeof(
float);
184 size_t data_space_expected = (size_t)
size[0] *
size[1] *
size[2] *
max_ii(1, layers) *
185 component_len * component_size_expected;
187 data_space_expected *= 6 *
size[0];
191 PyErr_SetString(PyExc_ValueError,
"GPUTexture.__new__: Buffer size smaller than requested");
198 if (is_cubemap &&
len != 1) {
200 "In cubemaps the same dimension represents height, width and depth. No tuple needed");
203 STRNCPY(err_out,
"Values less than 1 are not allowed in dimensions");
205 else if (layers &&
len == 3) {
206 STRNCPY(err_out,
"3D textures have no layers");
209 STRNCPY(err_out,
"No active GPU context found");
212 const char *name =
"python_texture";
252 PyErr_Format(PyExc_RuntimeError,
"gpu.texture.new(...) failed with '%s'", err_out);
259 PyDoc_STRVAR(pygpu_texture_width_doc,
"Width of the texture.\n\n:type: `int`");
266 PyDoc_STRVAR(pygpu_texture_height_doc,
"Height of the texture.\n\n:type: `int`");
273 PyDoc_STRVAR(pygpu_texture_format_doc,
"Format of the texture.\n\n:type: `str`");
282 pygpu_texture_clear_doc,
283 ".. method:: clear(format='FLOAT', value=(0.0, 0.0, 0.0, 1.0))\n"
285 " Fill texture with specific value.\n"
287 " :param format: The format that describes the content of a single item.\n"
288 " Possible values are `FLOAT`, `INT`, `UINT`, `UBYTE`, `UINT_24_8` and `10_11_11_REV`.\n"
290 " :arg value: sequence each representing the value to fill.\n"
291 " :type value: sequence of 1, 2, 3 or 4 values\n");
304 static const char *_keywords[] = {
"format",
"value",
NULL};
305 static _PyArg_Parser _parser = {
"$O&O:clear", _keywords, 0};
306 if (!_PyArg_ParseTupleAndKeywordsFast(
311 int shape = PySequence_Size(py_values);
317 PyErr_SetString(PyExc_AttributeError,
"too many dimensions, max is 4");
323 PyErr_SetString(PyExc_AttributeError,
324 "`UINT_24_8` and `10_11_11_REV` only support single values");
328 memset(&values, 0,
sizeof(values));
340 values.c[0] = values.i[0];
341 values.c[1] = values.i[1];
342 values.c[2] = values.i[2];
343 values.c[3] = values.i[3];
351 ".. method:: read()\n"
353 " Creates a buffer with the value of all pixels.\n"
363 switch (tex_format) {
403 int shape_len = (shape[2] == 1) ? 2 : 3;
407 #ifdef BPYGPU_USE_GPUOBJ_FREE_METHOD
409 ".. method:: free()\n"
411 " Free the texture object.\n"
412 " The texture object will no longer be accessible.\n");
428 Py_TYPE(
self)->tp_free((PyObject *)
self);
441 METH_VARARGS | METH_KEYWORDS,
442 pygpu_texture_clear_doc},
444 #ifdef BPYGPU_USE_GPUOBJ_FREE_METHOD
445 {
"free", (PyCFunction)pygpu_texture_free, METH_NOARGS, pygpu_texture_free_doc},
451 pygpu_texture__tp_doc,
452 ".. class:: GPUTexture(size, layers=0, is_cubemap=False, format='RGBA8', data=None)\n"
454 " This object gives access to off GPU textures.\n"
456 " :arg size: Dimensions of the texture 1D, 2D, 3D or cubemap.\n"
457 " :type size: tuple or int\n"
458 " :arg layers: Number of layers in texture array or number of cubemaps in cubemap array\n"
459 " :type layers: int\n"
460 " :arg is_cubemap: Indicates the creation of a cubemap texture.\n"
461 " :type is_cubemap: int\n"
462 " :arg format: Internal data format inside GPU memory. Possible values are:\n"
493 " `R11F_G11F_B10F`,\n"
494 " `DEPTH32F_STENCIL8`,\n"
495 " `DEPTH24_STENCIL8`,\n"
498 " `SRGB8_A8_DXT1`,\n"
499 " `SRGB8_A8_DXT3`,\n"
500 " `SRGB8_A8_DXT5`,\n"
504 " `DEPTH_COMPONENT32F`,\n"
505 " `DEPTH_COMPONENT24`,\n"
506 " `DEPTH_COMPONENT16`,\n"
507 " :type format: str\n"
508 " :arg data: Buffer object to fill the texture.\n"
509 " :type data: :class:`gpu.types.Buffer`\n");
511 PyVarObject_HEAD_INIT(
NULL, 0).tp_name =
"GPUTexture",
514 .tp_flags = Py_TPFLAGS_DEFAULT,
515 .tp_doc = pygpu_texture__tp_doc,
527 ".. function:: from_image(image)\n"
529 " Get GPUTexture corresponding to an Image datablock. The GPUTexture memory is "
530 "shared with Blender.\n"
531 " Note: Colors read from the texture will be in scene linear color space and have "
532 "premultiplied or straight alpha matching the image alpha mode.\n"
534 " :arg image: The Image datablock.\n"
535 " :type image: `bpy.types.Image`\n"
536 " :return: The GPUTexture used by the image.\n"
537 " :rtype: :class:`gpu.types.GPUTexture`\n");
560 PyDoc_STRVAR(pygpu_texure__m_doc,
"This module provides utils for textures.");
562 PyModuleDef_HEAD_INIT,
563 .m_name =
"gpu.texture",
564 .m_doc = pygpu_texure__m_doc,
583 PyExc_ValueError,
"expected a texture or None object, got %s", Py_TYPE(o)->tp_name);
616 return (PyObject *)
self;
621 #undef BPYGPU_TEXTURE_CHECK_OBJ
typedef float(TangentPoint)[2]
struct GPUTexture * BKE_image_get_gpu_texture(struct Image *image, struct ImageUser *iuser, struct ImBuf *ibuf)
void BKE_imageuser_default(struct ImageUser *iuser)
MINLINE int max_ii(int a, int b)
#define STRNCPY(dst, src)
GPUContext * GPU_context_active_get(void)
_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
GPUTexture * GPU_texture_create_2d_array(const char *name, int w, int h, int d, int mip_len, eGPUTextureFormat format, const float *data)
GPUTexture * GPU_texture_create_1d_array(const char *name, int w, int h, int mip_len, eGPUTextureFormat format, const float *data)
int GPU_texture_height(const GPUTexture *tex)
GPUTexture * GPU_texture_create_1d(const char *name, int w, int mip_len, eGPUTextureFormat format, const float *data)
void GPU_texture_clear(GPUTexture *tex, eGPUDataFormat data_format, const void *data)
struct GPUTexture GPUTexture
int GPU_texture_width(const GPUTexture *tex)
void * GPU_texture_read(GPUTexture *tex, eGPUDataFormat data_format, int miplvl)
void GPU_texture_ref(GPUTexture *tex)
void GPU_texture_free(GPUTexture *tex)
GPUTexture * GPU_texture_create_2d(const char *name, int w, int h, int mip_len, eGPUTextureFormat format, const float *data)
GPUTexture * GPU_texture_create_3d(const char *name, int w, int h, int d, int mip_len, eGPUTextureFormat texture_format, eGPUDataFormat data_format, const void *data)
eGPUTextureFormat GPU_texture_format(const GPUTexture *tex)
GPUTexture * GPU_texture_create_cube(const char *name, int w, int mip_len, eGPUTextureFormat format, const float *data)
size_t GPU_texture_component_len(eGPUTextureFormat format)
GPUTexture * GPU_texture_create_cube_array(const char *name, int w, int d, int mip_len, eGPUTextureFormat format, const float *data)
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
struct PyC_StringEnumItems bpygpu_dataformat_items[]
#define BPYGPU_IS_INIT_OR_ERROR_OBJ
BPyGPUBuffer * BPyGPU_Buffer_CreatePyObject(const int format, const Py_ssize_t *shape, const int shape_len, void *buffer)
PyTypeObject BPyGPU_BufferType
size_t bpygpu_Buffer_size(BPyGPUBuffer *buffer)
#define BPYGPU_USE_GPUOBJ_FREE_METHOD
static PyObject * pygpu_texture_read(BPyGPUTexture *self)
static PyObject * pygpu_texture_format_get(BPyGPUTexture *self, void *UNUSED(type))
PyTypeObject BPyGPUTexture_Type
static PyObject * pygpu_texture__tp_new(PyTypeObject *UNUSED(self), PyObject *args, PyObject *kwds)
static struct PyMethodDef pygpu_texture__m_methods[]
static struct PyMethodDef pygpu_texture__tp_methods[]
PyObject * bpygpu_texture_init(void)
static const struct PyC_StringEnumItems pygpu_textureformat_items[]
static void BPyGPUTexture__tp_dealloc(BPyGPUTexture *self)
PyObject * BPyGPUTexture_CreatePyObject(GPUTexture *tex)
static PyObject * pygpu_texture_clear(BPyGPUTexture *self, PyObject *args, PyObject *kwds)
static int pygpu_texture_valid_check(BPyGPUTexture *bpygpu_tex)
static PyGetSetDef pygpu_texture__tp_getseters[]
static PyObject * pygpu_texture_width_get(BPyGPUTexture *self, void *UNUSED(type))
PyDoc_STRVAR(pygpu_texture_width_doc, "Width of the texture.\n\n:type: `int`")
#define BPYGPU_TEXTURE_CHECK_OBJ(bpygpu)
int bpygpu_ParseTexture(PyObject *o, void *p)
static PyObject * pygpu_texture_from_image(PyObject *UNUSED(self), PyObject *arg)
static PyObject * pygpu_texture_height_get(BPyGPUTexture *self, void *UNUSED(type))
static PyModuleDef pygpu_texture_module_def
struct BPyGPUTexture BPyGPUTexture
#define BPyGPUTexture_Check(v)
int PyC_ParseStringEnum(PyObject *o, void *p)
void * PyC_RNA_AsPointer(PyObject *value, const char *type_name)
const char * PyC_StringEnum_FindIDFromValue(const struct PyC_StringEnumItems *items, const int value)
int PyC_AsArray(void *array, PyObject *value, const Py_ssize_t length, const PyTypeObject *type, const bool is_double, const char *error_prefix)
union BPyGPUBuffer::@1119 buf
PyObject_HEAD struct GPUTexture * tex