88 PyErr_SetString(PyExc_ReferenceError,
90 "GPU texture was freed, no further access is valid"
92 "GPU texture: internal error"
101#define BPYGPU_TEXTURE_CHECK_OBJ(bpygpu) \
103 if (UNLIKELY(pygpu_texture_valid_check(bpygpu) == -1)) { \
120 int size[3] = {1, 1, 1};
122 int is_cubemap =
false;
125 char err_out[256] =
"unknown error. See console";
127 static const char *_keywords[] = {
"size",
"layers",
"is_cubemap",
"format",
"data",
nullptr};
128 static _PyArg_Parser _parser = {
136 ":GPUTexture.__new__",
140 if (!_PyArg_ParseTupleAndKeywordsFast(args,
147 &pygpu_textureformat,
155 if (PySequence_Check(py_size)) {
156 len = PySequence_Size(py_size);
157 if ((
len < 1) || (
len > 3)) {
158 PyErr_Format(PyExc_ValueError,
159 "GPUTexture.__new__: \"size\" must be between 1 and 3 in length (got %d)",
163 if (
PyC_AsArray(size,
sizeof(*size), py_size,
len, &PyLong_Type,
"GPUTexture.__new__") == -1) {
167 else if (PyLong_Check(py_size)) {
168 size[0] = PyLong_AsLong(py_size);
171 PyErr_SetString(PyExc_ValueError,
"GPUTexture.__new__: Expected an int or tuple as first arg");
175 void *data =
nullptr;
178 PyErr_SetString(PyExc_ValueError,
179 "GPUTexture.__new__: Only Buffer of format `FLOAT` is currently supported");
185 int component_size_expected =
sizeof(
float);
186 size_t data_space_expected = size_t(size[0]) * size[1] * size[2] *
max_ii(1, layers) *
187 component_len * component_size_expected;
189 data_space_expected *= 6 * size[0];
193 PyErr_SetString(PyExc_ValueError,
"GPUTexture.__new__: Buffer size smaller than requested");
199 GPUTexture *
tex =
nullptr;
200 if (is_cubemap &&
len != 1) {
202 "In cubemaps the same dimension represents height, width and depth. No tuple needed");
204 else if (size[0] < 1 || size[1] < 1 || size[2] < 1) {
205 STRNCPY(err_out,
"Values less than 1 are not allowed in dimensions");
207 else if (layers &&
len == 3) {
208 STRNCPY(err_out,
"3D textures have no layers");
211 STRNCPY(err_out,
"No active GPU context found");
214 const char *name =
"python_texture";
224 static_cast<const float *
>(data));
232 static_cast<const float *
>(data));
244 static_cast<const float *
>(data));
253 static_cast<const float *
>(data));
273 static_cast<const float *
>(data));
281 static_cast<const float *
>(data));
285 if (
tex ==
nullptr) {
286 PyErr_Format(PyExc_RuntimeError,
"gpu.texture.new(...) failed with '%s'", err_out);
295 pygpu_texture_width_doc,
296 "Width of the texture.\n"
307 pygpu_texture_height_doc,
308 "Height of the texture.\n"
319 pygpu_texture_format_doc,
320 "Format of the texture.\n"
332 pygpu_texture_clear_doc,
333 ".. method:: clear(format='FLOAT', value=(0.0, 0.0, 0.0, 1.0))\n"
335 " Fill texture with specific value.\n"
337 " :arg format: The format that describes the content of a single item.\n"
338 " Possible values are `FLOAT`, `INT`, `UINT`, `UBYTE`, `UINT_24_8` and `10_11_11_REV`.\n"
339 " :type format: str\n"
340 " :arg value: Sequence each representing the value to fill. Sizes 1..4 are supported.\n"
341 " :type value: Sequence[float]\n");
354 static const char *_keywords[] = {
"format",
"value",
nullptr};
355 static _PyArg_Parser _parser = {
364 if (!_PyArg_ParseTupleAndKeywordsFast(
370 int shape = PySequence_Size(py_values);
376 PyErr_SetString(PyExc_AttributeError,
"too many dimensions, max is 4");
382 PyErr_SetString(PyExc_AttributeError,
383 "`UINT_24_8` and `10_11_11_REV` only support single values");
387 memset(&values, 0,
sizeof(values));
401 values.c[0] = values.i[0];
402 values.c[1] = values.i[1];
403 values.c[2] = values.i[2];
404 values.c[3] = values.i[3];
413 pygpu_texture_read_doc,
414 ".. method:: read()\n"
416 " Creates a buffer with the value of all pixels.\n"
426 switch (tex_format) {
466 int shape_len = (shape[2] == 1) ? 2 : 3;
470#ifdef BPYGPU_USE_GPUOBJ_FREE_METHOD
473 pygpu_texture_free_doc,
474 ".. method:: free()\n"
476 " Free the texture object.\n"
477 " The texture object will no longer be accessible.\n");
491#ifndef GPU_NO_USE_PY_REFERENCES
496 Py_TYPE(
self)->tp_free((PyObject *)
self);
504 pygpu_texture_height_doc,
509 pygpu_texture_format_doc,
511 {
nullptr,
nullptr,
nullptr,
nullptr,
nullptr}
514#if (defined(__GNUC__) && !defined(__clang__))
515# pragma GCC diagnostic push
516# pragma GCC diagnostic ignored "-Wcast-function-type"
522 METH_VARARGS | METH_KEYWORDS,
523 pygpu_texture_clear_doc},
525#ifdef BPYGPU_USE_GPUOBJ_FREE_METHOD
526 {
"free", (PyCFunction)pygpu_texture_free, METH_NOARGS, pygpu_texture_free_doc},
528 {
nullptr,
nullptr, 0,
nullptr},
531#if (defined(__GNUC__) && !defined(__clang__))
532# pragma GCC diagnostic pop
537 pygpu_texture__tp_doc,
538 ".. class:: GPUTexture(size, layers=0, is_cubemap=False, format='RGBA8', data=None)\n"
540 " This object gives access to off GPU textures.\n"
542 " :arg size: Dimensions of the texture 1D, 2D, 3D or cubemap.\n"
543 " :type size: int | Sequence[int]\n"
544 " :arg layers: Number of layers in texture array or number of cubemaps in cubemap array\n"
545 " :type layers: int\n"
546 " :arg is_cubemap: Indicates the creation of a cubemap texture.\n"
547 " :type is_cubemap: int\n"
548 " :arg format: Internal data format inside GPU memory. Possible values are:\n"
579 " `R11F_G11F_B10F`,\n"
580 " `DEPTH32F_STENCIL8`,\n"
581 " `DEPTH24_STENCIL8`,\n"
584 " `SRGB8_A8_DXT1`,\n"
585 " `SRGB8_A8_DXT3`,\n"
586 " `SRGB8_A8_DXT5`,\n"
590 " `DEPTH_COMPONENT32F`,\n"
591 " `DEPTH_COMPONENT24`,\n"
592 " `DEPTH_COMPONENT16`,\n"
593 " :type format: str\n"
594 " :arg data: Buffer object to fill the texture.\n"
595 " :type data: :class:`gpu.types.Buffer`\n");
597 PyVarObject_HEAD_INIT(
nullptr, 0)
617 pygpu_texture__tp_doc,
656 pygpu_texture_from_image_doc,
657 ".. function:: from_image(image)\n"
659 " Get GPUTexture corresponding to an Image datablock. The GPUTexture memory is "
660 "shared with Blender.\n"
661 " Note: Colors read from the texture will be in scene linear color space and have "
662 "premultiplied or straight alpha matching the image alpha mode.\n"
664 " :arg image: The Image datablock.\n"
665 " :type image: :class:`bpy.types.Image`\n"
666 " :return: The GPUTexture used by the image.\n"
667 " :rtype: :class:`gpu.types.GPUTexture`\n");
671 if (ima ==
nullptr) {
684 {
nullptr,
nullptr, 0,
nullptr},
689 pygpu_texture__m_doc,
690 "This module provides utils for textures.");
692 PyModuleDef_HEAD_INIT,
694 pygpu_texture__m_doc,
712 *(GPUTexture **)p =
nullptr;
718 PyExc_ValueError,
"expected a texture or None object, got %s", Py_TYPE(o)->tp_name);
748 if (shared_reference) {
749#ifndef GPU_NO_USE_PY_REFERENCES
756 return (PyObject *)
self;
766#ifndef GPU_NO_USE_PY_REFERENCES
771 return (PyObject *)
self;
776#undef BPYGPU_TEXTURE_CHECK_OBJ
void BKE_imageuser_default(ImageUser *iuser)
GPUTexture * BKE_image_get_gpu_texture(Image *image, ImageUser *iuser)
MINLINE int max_ii(int a, int b)
#define STRNCPY(dst, src)
#define POINTER_OFFSET(v, ofs)
GPUContext * GPU_context_active_get()
int GPU_texture_height(const GPUTexture *texture)
GPUTexture * GPU_texture_create_2d(const char *name, int width, int height, int mip_len, eGPUTextureFormat format, eGPUTextureUsage usage, const float *data)
GPUTexture * GPU_texture_create_1d(const char *name, int width, int mip_len, eGPUTextureFormat format, eGPUTextureUsage usage, const float *data)
void GPU_texture_free(GPUTexture *texture)
int GPU_texture_width(const GPUTexture *texture)
void GPU_texture_clear(GPUTexture *texture, eGPUDataFormat data_format, const void *data)
void GPU_texture_ref(GPUTexture *texture)
void ** GPU_texture_py_reference_get(GPUTexture *texture)
void * GPU_texture_read(GPUTexture *texture, eGPUDataFormat data_format, int mip_level)
void GPU_texture_py_reference_set(GPUTexture *texture, void **py_ref)
GPUTexture * GPU_texture_create_cube_array(const char *name, int width, int layer_len, int mip_len, eGPUTextureFormat format, eGPUTextureUsage usage, const float *data)
@ GPU_TEXTURE_USAGE_GENERAL
GPUTexture * GPU_texture_create_2d_array(const char *name, int width, int height, int layer_len, int mip_len, eGPUTextureFormat format, eGPUTextureUsage usage, const float *data)
GPUTexture * GPU_texture_create_3d(const char *name, int width, int height, int depth, int mip_len, eGPUTextureFormat format, eGPUTextureUsage usage, const void *data)
GPUTexture * GPU_texture_create_cube(const char *name, int width, int mip_len, eGPUTextureFormat format, eGPUTextureUsage usage, const float *data)
GPUTexture * GPU_texture_create_1d_array(const char *name, int width, int layer_len, int mip_len, eGPUTextureFormat format, eGPUTextureUsage usage, const float *data)
size_t GPU_texture_component_len(eGPUTextureFormat format)
eGPUTextureFormat GPU_texture_format(const GPUTexture *texture)
additional_info("compositor_sum_float_shared") .push_constant(Type additional_info("compositor_sum_float_shared") .push_constant(Type GPU_RGBA32F
DOF_TILES_FLATTEN_GROUP_SIZE coc_tx GPU_R11F_G11F_B10F
draw_view in_light_buf[] float
out_radiance out_gbuf_normal out_gbuf_closure2 GPU_RG16
SHADOW_TILEMAP_RES tiles_buf[] statistics_buf render_view_buf[SHADOW_VIEW_MAX] GPU_R32UI
RAYTRACE_GROUP_SIZE additional_info("eevee_shared", "eevee_gbuffer_data", "eevee_global_ubo", "eevee_sampling_data", "eevee_utility_texture", "eevee_hiz_data", "draw_view") .specialization_constant(Type RAYTRACE_GROUP_SIZE in_sh_0_tx in_sh_2_tx screen_normal_tx GPU_RGBA8
PyC_StringEnumItems bpygpu_dataformat_items[]
#define BPYGPU_IS_INIT_OR_ERROR_OBJ
PyTypeObject BPyGPU_BufferType
BPyGPUBuffer * BPyGPU_Buffer_CreatePyObject(const int format, const Py_ssize_t *shape, const int shape_len, void *buffer)
size_t bpygpu_Buffer_size(BPyGPUBuffer *buffer)
#define BPYGPU_USE_GPUOBJ_FREE_METHOD
PyTypeObject BPyGPUTexture_Type
static PyObject * pygpu_texture_width_get(BPyGPUTexture *self, void *)
PyObject * BPyGPUTexture_CreatePyObject(GPUTexture *tex, bool shared_reference)
static PyObject * pygpu_texture_clear(BPyGPUTexture *self, PyObject *args, PyObject *kwds)
PyObject * bpygpu_texture_init()
PyDoc_STRVAR(pygpu_texture_width_doc, "Width of the texture.\n" "\n" ":type: int")
static void BPyGPUTexture__tp_dealloc(BPyGPUTexture *self)
static int pygpu_texture_valid_check(BPyGPUTexture *bpygpu_tex)
static PyGetSetDef pygpu_texture__tp_getseters[]
#define BPYGPU_TEXTURE_CHECK_OBJ(bpygpu)
static PyObject * pygpu_texture_from_image(PyObject *, PyObject *arg)
static PyObject * pygpu_texture__tp_new(PyTypeObject *, PyObject *args, PyObject *kwds)
static PyObject * pygpu_texture_height_get(BPyGPUTexture *self, void *)
int bpygpu_ParseTexture(PyObject *o, void *p)
static PyObject * pygpu_texture_read(BPyGPUTexture *self)
const PyC_StringEnumItems pygpu_textureformat_items[]
static PyMethodDef pygpu_texture__m_methods[]
static PyMethodDef pygpu_texture__tp_methods[]
static PyModuleDef pygpu_texture_module_def
static PyObject * pygpu_texture_format_get(BPyGPUTexture *self, void *)
#define BPyGPUTexture_Check(v)
void * PyC_RNA_AsPointer(PyObject *value, const char *type_name)
int PyC_ParseStringEnum(PyObject *o, void *p)
int PyC_AsArray(void *array, const size_t array_item_size, PyObject *value, const Py_ssize_t length, const PyTypeObject *type, const char *error_prefix)
const char * PyC_StringEnum_FindIDFromValue(const PyC_StringEnumItems *items, const int value)
header-only compatibility defines.
#define PY_ARG_PARSER_HEAD_COMPAT()
union BPyGPUBuffer::@1342 buf
PyObject_HEAD GPUTexture * tex