Blender V4.3
gpu_py_compute.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
12#include <Python.h>
13
14#include "BLI_utildefines.h"
15
16#include "GPU_capabilities.hh"
17#include "GPU_compute.hh"
18#include "GPU_state.hh"
19
21
22#include "gpu_py.hh"
23#include "gpu_py_compute.hh" /* own include */
24#include "gpu_py_shader.hh"
25
27 /* Wrap. */
28 pygpu_compute_dispatch_doc,
29 ".. function:: dispatch(shader, groups_x_len, groups_y_len, groups_z_len)\n"
30 "\n"
31 " Dispatches GPU compute.\n"
32 "\n"
33 " :arg shader: The shader that you want to dispatch.\n"
34 " :type shader: :class:`gpu.types.GPUShader`\n"
35 " :arg groups_x_len: Int for group x length:\n"
36 " :type groups_x_len: int\n"
37 " :arg groups_y_len: Int for group y length:\n"
38 " :type groups_y_len: int\n"
39 " :arg groups_z_len: Int for group z length:\n"
40 " :type groups_z_len: int\n"
41 " :return: Shader object.\n"
42 " :rtype: :class:`gpu.types.GPUShader`\n");
43static PyObject *pygpu_compute_dispatch(PyObject * /*self*/, PyObject *args, PyObject *kwds)
44{
46
47 BPyGPUShader *py_shader;
48 int groups_x_len;
49 int groups_y_len;
50 int groups_z_len;
51
52 static const char *_keywords[] = {
53 "shader", "groups_x_len", "groups_y_len", "groups_z_len", nullptr};
54 static _PyArg_Parser _parser = {
56 "O" /* `shader` */
57 "i" /* `groups_x_len` */
58 "i" /* `groups_y_len` */
59 "i" /* `groups_z_len` */
60 ":dispatch",
61 _keywords,
62 nullptr,
63 };
64 if (_PyArg_ParseTupleAndKeywordsFast(
65 args, kwds, &_parser, &py_shader, &groups_x_len, &groups_y_len, &groups_z_len))
66 {
67 if (!BPyGPUShader_Check(py_shader)) {
68 PyErr_Format(PyExc_TypeError, "Expected a GPUShader, got %s", Py_TYPE(py_shader)->tp_name);
69 return nullptr;
70 }
71
72 /* Check that groups do not exceed #GPU_max_work_group_count(). */
73 const int max_work_group_count_x = GPU_max_work_group_count(0);
74 const int max_work_group_count_y = GPU_max_work_group_count(1);
75 const int max_work_group_count_z = GPU_max_work_group_count(2);
76
77 /* Report back to the user both the requested and the maximum supported value. */
78 if (groups_x_len > GPU_max_work_group_count(0)) {
79 PyErr_Format(PyExc_ValueError,
80 "groups_x_len (%d) exceeds maximum supported value (max work group count: %d)",
81 groups_x_len,
82 max_work_group_count_x);
83 return nullptr;
84 }
85 if (groups_y_len > GPU_max_work_group_count(1)) {
86 PyErr_Format(PyExc_ValueError,
87 "groups_y_len (%d) exceeds maximum supported value (max work group count: %d)",
88 groups_y_len,
89 max_work_group_count_y);
90 return nullptr;
91 }
92 if (groups_z_len > GPU_max_work_group_count(2)) {
93 PyErr_Format(PyExc_ValueError,
94 "groups_z_len (%d) exceeds maximum supported value (max work group count: %d)",
95 groups_z_len,
96 max_work_group_count_z);
97 return nullptr;
98 }
99
100 GPUShader *shader = py_shader->shader;
101 GPU_compute_dispatch(shader, groups_x_len, groups_y_len, groups_z_len);
103 }
104 Py_RETURN_NONE;
105}
106
107/* -------------------------------------------------------------------- */
111static PyMethodDef pygpu_compute__tp_methods[] = {
112 {"dispatch",
113 (PyCFunction)pygpu_compute_dispatch,
114 METH_VARARGS | METH_KEYWORDS,
115 pygpu_compute_dispatch_doc},
116 {nullptr, nullptr, 0, nullptr},
117};
118
119#if (defined(__GNUC__) && !defined(__clang__))
120# pragma GCC diagnostic pop
121#endif
122
124 /* Wrap. */
125 pygpu_compute__tp_doc,
126 "This module provides access to the global GPU compute functions");
127static PyModuleDef pygpu_compute_module_def = {
128 /*m_base*/ PyModuleDef_HEAD_INIT,
129 /*m_name*/ "gpu.compute",
130 /*m_doc*/ pygpu_compute__tp_doc,
131 /*m_size*/ 0,
132 /*m_methods*/ pygpu_compute__tp_methods,
133 /*m_slots*/ nullptr,
134 /*m_traverse*/ nullptr,
135 /*m_clear*/ nullptr,
136 /*m_free*/ nullptr,
137};
138
140{
141 PyObject *submodule;
142
143 submodule = PyModule_Create(&pygpu_compute_module_def);
144
145 return submodule;
146}
147
int GPU_max_work_group_count(int index)
void GPU_compute_dispatch(GPUShader *shader, uint groups_x_len, uint groups_y_len, uint groups_z_len)
void GPU_memory_barrier(eGPUBarrier barrier)
Definition gpu_state.cc:374
@ GPU_BARRIER_TEXTURE_FETCH
Definition GPU_state.hh:37
@ GPU_BARRIER_SHADER_IMAGE_ACCESS
Definition GPU_state.hh:35
struct GPUShader GPUShader
#define BPYGPU_IS_INIT_OR_ERROR_OBJ
Definition gpu_py.hh:18
PyDoc_STRVAR(pygpu_compute_dispatch_doc, ".. function:: dispatch(shader, groups_x_len, groups_y_len, groups_z_len)\n" "\n" " Dispatches GPU compute.\n" "\n" " :arg shader: The shader that you want to dispatch.\n" " :type shader: :class:`gpu.types.GPUShader`\n" " :arg groups_x_len: Int for group x length:\n" " :type groups_x_len: int\n" " :arg groups_y_len: Int for group y length:\n" " :type groups_y_len: int\n" " :arg groups_z_len: Int for group z length:\n" " :type groups_z_len: int\n" " :return: Shader object.\n" " :rtype: :class:`gpu.types.GPUShader`\n")
static PyMethodDef pygpu_compute__tp_methods[]
PyObject * bpygpu_compute_init()
static PyObject * pygpu_compute_dispatch(PyObject *, PyObject *args, PyObject *kwds)
static PyModuleDef pygpu_compute_module_def
#define BPyGPUShader_Check(v)
header-only compatibility defines.
#define PY_ARG_PARSER_HEAD_COMPAT()
PyObject_VAR_HEAD struct GPUShader * shader