PyGPU: Show error for unsupported POLYLINE shader configurations

In Blender 4.4 (since commit 00a8d006fe), polyline shaders stopped
using geometry shaders and now rely on SSBOs.

In C++, workarounds allow these shaders to function as before, albeit
with some limitations.

To address these known limitations, error messages are now raised when
a polyline shader is used with unsupported configurations.

Pull Request: https://projects.blender.org/blender/blender/pulls/131055
This commit is contained in:
Germano Cavalcante
2024-12-11 12:34:37 -03:00
committed by Gitea
parent 19fee82b72
commit 179f2a3cb1

View File

@@ -224,6 +224,62 @@ static PyObject *pygpu_batch_program_set(BPyGPUBatch *self, BPyGPUShader *py_sha
Py_RETURN_NONE;
}
/**
* Verify if the Shader is compatible with the batch and can be used for rendering.
* Derived from `polyline_draw_workaround` in `gpu_immediate.cc`.
*/
static const char *pygpu_shader_check_compatibility(blender::gpu::Batch *batch)
{
if (!batch->shader) {
return nullptr;
}
/* Currently only POLYLINE shaders are checked. */
if (!bpygpu_shader_is_polyline(batch->shader)) {
return nullptr;
}
/* Check batch compatibility with shader. */
for (auto vert : blender::Span(batch->verts, ARRAY_SIZE(batch->verts))) {
if (!vert) {
continue;
}
GPUVertFormat &format = vert->format;
if ((format.stride % 4) != 0) {
return "For POLYLINE shaders, only 4-byte aligned formats are supported";
}
int pos_attr_id = -1;
int col_attr_id = -1;
for (uint a_idx = 0; a_idx < format.attr_len; a_idx++) {
const GPUVertAttr *a = &format.attrs[a_idx];
if ((a->offset % 4) != 0) {
return "For POLYLINE shaders, only 4-byte aligned attributes are supported";
}
const blender::StringRefNull name = GPU_vertformat_attr_name_get(&format, a, 0);
if (pos_attr_id == -1 && name == "pos") {
if (!ELEM(a->comp_type, GPU_COMP_F32)) {
return "For POLYLINE shaders, the 'pos' attribute needs to be 'F32'";
}
if (!ELEM(a->fetch_mode, GPU_FETCH_FLOAT)) {
return "For POLYLINE shaders, the 'pos' attribute must use the 'FLOAT' fetch type";
}
pos_attr_id = a_idx;
}
else if (col_attr_id == -1 && name == "color") {
if (!ELEM(a->comp_type, GPU_COMP_F32, GPU_COMP_U8)) {
return "For POLYLINE shaders, the 'color' attribute needs to be 'F32' or 'U8'";
}
col_attr_id = a_idx;
}
if (pos_attr_id != -1 && col_attr_id != -1) {
break;
}
}
}
return nullptr;
}
PyDoc_STRVAR(
/* Wrap. */
pygpu_batch_draw_doc,
@@ -262,6 +318,11 @@ static PyObject *pygpu_batch_draw(BPyGPUBatch *self, PyObject *args)
GPU_batch_set_shader(self->batch, py_shader->shader);
}
if (const char *error = pygpu_shader_check_compatibility(self->batch)) {
PyErr_SetString(PyExc_RuntimeError, error);
return nullptr;
}
GPU_batch_draw(self->batch);
Py_RETURN_NONE;
}