Revert "Benchmark: Vulkan device selection"

This reverts commit abe6a79025.
It breaks test cases (Pydoc)

Pull Request: https://projects.blender.org/blender/blender/pulls/159230
This commit is contained in:
Jeroen Bakker 2026-05-28 15:41:50 +02:00
parent c2613c76a3
commit 04a40d91a7
15 changed files with 11 additions and 261 deletions

View file

@ -263,9 +263,6 @@ void MTLBackend::platform_init(MTLContext *ctx)
version,
architecture_type);
GPG.devices.append(
{.identifier = "METAL", .index = 0, .vendor_id = 0, .device_id = 0, .name = renderer});
/* UUID is not supported on Metal. */
GPG.device_uuid.reinitialize(0);

View file

@ -331,9 +331,6 @@ void GLBackend::platform_init()
version,
GPU_ARCHITECTURE_IMR);
GPG.devices.append(
{.identifier = "OPENGL", .index = 0, .vendor_id = 0, .device_id = 0, .name = renderer});
GPG.device_uuid.reinitialize(0);
GPG.device_luid.reinitialize(0);
GPG.device_luid_node_mask = 0;

View file

@ -19,150 +19,6 @@
namespace blender {
/* -------------------------------------------------------------------- */
/** \name GPU Device Type
* \{ */
/* Property getters */
static PyObject *pygpu_device_index_get(BPyGPUDevice *self, void * /*closure*/)
{
return PyLong_FromLong(self->index);
}
static PyObject *pygpu_device_identifier_get(BPyGPUDevice *self, void * /*closure*/)
{
return PyUnicode_FromString(self->identifier);
}
static PyObject *pygpu_device_name_get(BPyGPUDevice *self, void * /*closure*/)
{
return PyUnicode_FromString(self->name);
}
/* Property descriptors */
static PyGetSetDef pygpu_device_getseters[] = {
{"index", reinterpret_cast<getter>(pygpu_device_index_get), nullptr, "Device index.", nullptr},
{"identifier",
reinterpret_cast<getter>(pygpu_device_identifier_get),
nullptr,
"Device identifier.",
nullptr},
{"name", reinterpret_cast<getter>(pygpu_device_name_get), nullptr, "Device name.", nullptr},
{nullptr, nullptr, nullptr, nullptr, nullptr},
};
/* Representation */
static PyObject *pygpu_device__tp_repr(BPyGPUDevice *self)
{
return PyUnicode_FromFormat("<GPUDevice index=%d identifier=\"%s\" name=\"%s\">",
self->index,
self->identifier,
self->name);
}
/** Rich comparison for GPUDevice types, compares by index. */
static PyObject *pygpu_device__tp_richcmp(BPyGPUDevice *self, PyObject *other, int op)
{
if (!Py_IS_TYPE(other, &BPyGPU_DeviceType)) {
Py_RETURN_NOTIMPLEMENTED;
}
BPyGPUDevice *other_device = reinterpret_cast<BPyGPUDevice *>(other);
switch (op) {
case Py_LT:
return PyBool_FromLong(self->index < other_device->index);
case Py_LE:
return PyBool_FromLong(self->index <= other_device->index);
case Py_EQ:
return PyBool_FromLong(self->index == other_device->index);
case Py_NE:
return PyBool_FromLong(self->index != other_device->index);
case Py_GT:
return PyBool_FromLong(self->index > other_device->index);
case Py_GE:
return PyBool_FromLong(self->index >= other_device->index);
}
Py_RETURN_NOTIMPLEMENTED;
}
/* Type definition */
PyDoc_STRVAR(pygpu_device__tp_doc,
".. class:: GPUDevice\n"
"\n"
" Represents a GPU device.\n"
"\n"
" :ivar int index: Device index.\n"
" :vartype int: index\n"
" :ivar str identifier: Device identifier.\n"
" :vartype str: identifier\n"
" :ivar str name: Device name.\n"
" :vartype str: name\n");
PyTypeObject BPyGPU_DeviceType = {
/*ob_base*/ PyVarObject_HEAD_INIT(nullptr, 0)
/*tp_name*/ "gpu.platform.GPUDevice",
/*tp_basicsize*/ sizeof(BPyGPUDevice),
/*tp_itemsize*/ 0,
/*tp_dealloc*/ nullptr,
/*tp_vectorcall_offset*/ 0,
/*tp_getattr*/ nullptr,
/*tp_setattr*/ nullptr,
/*tp_compare*/ nullptr,
/*tp_repr*/ reinterpret_cast<reprfunc>(pygpu_device__tp_repr),
/*tp_as_number*/ nullptr,
/*tp_as_sequence*/ nullptr,
/*tp_as_mapping*/ nullptr,
/*tp_hash*/ nullptr,
/*tp_call*/ nullptr,
/*tp_str*/ nullptr,
/*tp_getattro*/ nullptr,
/*tp_setattro*/ nullptr,
/*tp_as_buffer*/ nullptr,
/*tp_flags*/ Py_TPFLAGS_DEFAULT,
/*tp_doc*/ pygpu_device__tp_doc,
/*tp_traverse*/ nullptr,
/*tp_clear*/ nullptr,
/*tp_richcompare*/ reinterpret_cast<richcmpfunc>(pygpu_device__tp_richcmp),
/*tp_weaklistoffset*/ 0,
/*tp_iter*/ nullptr,
/*tp_iternext*/ nullptr,
/*tp_methods*/ nullptr,
/*tp_members*/ nullptr,
/*tp_getset*/ pygpu_device_getseters,
/*tp_base*/ nullptr,
/*tp_dict*/ nullptr,
/*tp_descr_get*/ nullptr,
/*tp_descr_set*/ nullptr,
/*tp_dictoffset*/ 0,
/*tp_init*/ nullptr,
/*tp_alloc*/ nullptr,
/*tp_new*/ nullptr,
/*tp_free*/ nullptr,
/*tp_is_gc*/ nullptr,
/*tp_bases*/ nullptr,
/*tp_mro*/ nullptr,
/*tp_cache*/ nullptr,
/*tp_subclasses*/ nullptr,
/*tp_weaklist*/ nullptr,
/*tp_del*/ nullptr,
/*tp_version_tag*/ 0,
/*tp_finalize*/ nullptr,
/*tp_vectorcall*/ nullptr,
};
static BPyGPUDevice *pygpu_device_new(int index, const char *identifier, const char *name)
{
BPyGPUDevice *self = reinterpret_cast<BPyGPUDevice *>(
BPyGPU_DeviceType.tp_alloc(&BPyGPU_DeviceType, 0));
if (self != nullptr) {
self->index = index;
self->identifier = identifier;
self->name = name;
}
return self;
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Functions
* \{ */
@ -292,32 +148,6 @@ static PyObject *pygpu_platform_backend_type_get(PyObject * /*self*/)
return PyUnicode_FromString(backend);
}
PyDoc_STRVAR(
/* Wrap. */
pygpu_platform_devices_get_doc,
".. function:: devices_get()\n"
"\n"
" Get all available GPU devices.\n"
"\n"
" :return: List of :class:`GPUDevice` objects for each device.\n"
" :rtype: list of GPUDevice\n");
static PyObject *pygpu_platform_devices_get(PyObject * /*self*/)
{
BPYGPU_IS_INIT_OR_ERROR_OBJ;
Span<GPUDevice> devices = GPU_platform_devices_list();
PyObject *list = PyList_New(devices.size());
for (int i = 0; i < devices.size(); i++) {
const GPUDevice &dev = devices[i];
PyObject *item = reinterpret_cast<PyObject *>(
pygpu_device_new(dev.index, dev.identifier.c_str(), dev.name.c_str()));
PyList_SET_ITEM(list, i, item);
}
/* Sort by index (first attribute) for deterministic ordering. */
PyList_Sort(list);
return list;
}
/** \} */
/* -------------------------------------------------------------------- */
@ -355,10 +185,6 @@ static PyMethodDef pygpu_platform__tp_methods[] = {
reinterpret_cast<PyCFunction>(pygpu_platform_backend_type_get),
METH_NOARGS,
pygpu_platform_backend_type_get_doc},
{"devices_get",
reinterpret_cast<PyCFunction>(pygpu_platform_devices_get),
METH_NOARGS,
pygpu_platform_devices_get_doc},
{nullptr, nullptr, 0, nullptr},
};

View file

@ -12,16 +12,6 @@
namespace blender {
/* GPU Device Python object structure */
struct BPyGPUDevice {
PyObject_HEAD
int index;
const char *identifier;
const char *name;
};
extern PyTypeObject BPyGPU_DeviceType;
[[nodiscard]] PyObject *bpygpu_platform_init();
} // namespace blender

View file

@ -81,9 +81,6 @@ PyObject *bpygpu_types_init()
if (PyType_Ready(&PyGPUOffscreenStackContext_Type) < 0) {
return nullptr;
}
if (PyType_Ready(&BPyGPU_DeviceType) < 0) {
return nullptr;
}
PyModule_AddType(submodule, &BPyGPU_BufferType);
PyModule_AddType(submodule, &BPyGPUVertFormat_Type);
@ -99,7 +96,6 @@ PyObject *bpygpu_types_init()
PyModule_AddType(submodule, &BPyGPUStageInterfaceInfo_Type);
PyModule_AddType(submodule, &PyGPUMatrixStackContext_Type);
PyModule_AddType(submodule, &PyGPUOffscreenStackContext_Type);
PyModule_AddType(submodule, &BPyGPU_DeviceType);
return submodule;
}

View file

@ -15,7 +15,6 @@
#include "gpu_py_element.hh" // IWYU pragma: export
#include "gpu_py_framebuffer.hh" // IWYU pragma: export
#include "gpu_py_offscreen.hh" // IWYU pragma: export
#include "gpu_py_platform.hh" // IWYU pragma: export
#include "gpu_py_shader.hh" // IWYU pragma: export
#include "gpu_py_texture.hh" // IWYU pragma: export
#include "gpu_py_uniformbuffer.hh" // IWYU pragma: export

View file

@ -2,7 +2,6 @@
#
# SPDX-License-Identifier: Apache-2.0
from .common import normalize_device_id
from .environment import TestFailure, TestEnvironment
from .device import TestDevice, TestMachine
from .config import TestEntry, TestQueue, TestConfig

View file

@ -1,11 +0,0 @@
# SPDX-FileCopyrightText: 2026 Blender Authors
#
# SPDX-License-Identifier: Apache-2.0
def normalize_device_id(device_id: str) -> str:
"""Normalize a device ID by adding _0 suffix when there is no index."""
parts = device_id.rsplit('_', 1)
if len(parts) == 1 or not parts[1].isdigit():
return device_id + '_0'
return device_id

View file

@ -8,7 +8,6 @@ import pathlib
from dataclasses import dataclass, field
from .common import normalize_device_id
from .test import TestCollection
@ -97,7 +96,7 @@ class TestQueue:
rows = {}
for entry in entries:
key = (normalize_device_id(entry.device_id), entry.category, entry.test)
key = (entry.device_id, entry.category, entry.test)
if key in rows:
rows[key].append(entry)
else:
@ -106,13 +105,12 @@ class TestQueue:
return [value for _, value in sorted(rows.items())]
def find(self, revision: str, test: str, category: str, device_id: str) -> dict:
sanitized = normalize_device_id(device_id)
for entry in self.entries:
if (
entry.revision == revision and
entry.test == test and
entry.category == category and
normalize_device_id(entry.device_id) == sanitized
entry.device_id == device_id
):
return entry
@ -209,8 +207,7 @@ class TestConfig:
self.devices = []
for device in machine.devices:
for device_filter in device_filters:
if fnmatch.fnmatch(device.id, device_filter) or \
fnmatch.fnmatch(normalize_device_id(device.id), normalize_device_id(device_filter)):
if fnmatch.fnmatch(device.id, device_filter):
self.devices.append(device)
break
@ -248,7 +245,7 @@ class TestConfig:
devices = set()
for entry in entries:
categories.add(entry.category)
devices.add(entry.device_id)
devices.add(entry.device_type)
self.queue.has_multiple_categories = len(categories) > 1
self.queue.has_multiple_devices = len(devices) > 1

View file

@ -75,20 +75,8 @@ def get_gpu_device_backend(args: dict) -> dict:
result.append({'type': gpu_backend, 'name': gpu_backend})
prefs.system.gpu_backend = original_gpu_backend
else:
backend_type = gpu.platform.backend_type_get()
if backend_type != args['gpu_backend'].upper():
return {'devices': []}
try:
devices = gpu.platform.devices_get()
except (AttributeError, RuntimeError):
devices = []
if devices:
for device in devices:
result.append({'type': backend_type, 'name': device.name, 'index': device.index})
else:
result.append({'type': backend_type, 'name': gpu.platform.renderer_get()})
if gpu.platform.backend_type_get() == args['gpu_backend'].upper():
result.append({'type': gpu.platform.backend_type_get(), 'name': gpu.platform.renderer_get()})
return {'devices': result}

View file

@ -17,7 +17,6 @@ from collections.abc import (
Callable,
)
from .common import normalize_device_id
from .config import TestConfig
from .device import TestMachine
@ -422,9 +421,8 @@ class TestEnvironment:
device_id = device_str
gpu_backend = 'default'
sanitized_str = normalize_device_id(device_str)
for device in machine.devices:
if normalize_device_id(device.id) == sanitized_str or device.type == device_str:
if device.id == device_str or device.type == device_str:
device_id = device.id
gpu_backend = {
'VULKAN': 'vulkan',

View file

@ -38,23 +38,6 @@ class Test:
"""
return True
@staticmethod
def blender_gpu_arguments(device_id: str, gpu_backend: str) -> list:
"""
Return GPU arguments for blender.
Always includes --gpu-backend and optional include --gpu-device when device_id isn't
default (0 or missing).
"""
args = ['--gpu-backend', gpu_backend]
if '_' in device_id:
parts = device_id.rsplit('_', 1)
device_index = int(parts[1])
# Only specify --gpu-device for non-zero indices. Older builds could not support it.
if device_index > 0:
args += ['--gpu-device', str(device_index)]
return args
@abc.abstractmethod
def run(self, env, device_id: str, gpu_backend: str) -> dict:
"""

View file

@ -64,7 +64,7 @@ def print_row(table: api.MarkdownTable, entries: list, end='\n') -> None:
# For time series, revision is printed first.
row.append(entries[0].revision)
row.append(entries[0].category)
row.append(api.normalize_device_id(entries[0].device_id))
row.append(entries[0].device_type)
row.append(entries[0].test)
for entry in entries:
@ -136,7 +136,6 @@ def run_entry(env: api.TestEnvironment,
testcategory = entry.category
device_type = entry.device_type
device_id = entry.device_id
gpu_backend = {
'VULKAN': 'vulkan',
'METAL': 'metal',

View file

@ -143,11 +143,7 @@ else:
def run(self, env, device_id, gpu_backend):
args = {}
blender_args = api.test.Test.blender_gpu_arguments(device_id, gpu_backend)
blender_args.append(self.filepath)
_, log = env.run_in_blender(_run, args, blender_args, foreground=True)
_, log = env.run_in_blender(_run, args, ['--gpu-backend', gpu_backend, self.filepath], foreground=True)
for line in log:
if line.startswith(LOG_KEY):
result_str = line[len(LOG_KEY):]

View file

@ -111,13 +111,9 @@ class GreasePencilTest(api.Test):
def use_background(self):
return False
def run(self, env, device_id, gpu_backend):
def run(self, env, _device_id, gpu_backend):
args = {}
blender_args = api.test.Test.blender_gpu_arguments(device_id, gpu_backend)
blender_args.append(self.filepath)
_, log = env.run_in_blender(_run, args, blender_args, foreground=True)
_, log = env.run_in_blender(_run, args, ['--gpu-backend', gpu_backend, self.filepath], foreground=True)
for line in log:
if line.startswith(LOG_KEY):
result_str = line[len(LOG_KEY):]