Уровень абстракции API — избегайте смешивания интерфейсов API

Я планировал написать слой абстракции API для моего движка рендеринга. Два API, которые я хочу включить, это D3D11 и D3D12.
Итак, я начал с написания некоторых интерфейсов и их соответствующей реализации для каждого API.

Следующий фрагмент кода демонстрирует это:

class IDevice
{
//... (pure) virtual methods
};

class CD3D11Device : public IDevice
{
//... virtual method implementations
};

class CD3D12Device : public IDevice
{
//... virtual method implementations
};

Все идет нормально. Теперь к актуальной проблеме:
Если у меня есть другой интерфейс с методом, который требует IDevice* Как параметр, как я могу убедиться, что «правильное» устройство передается?

class ISomeClass
{
public:
virtual void foo(IDevice* pDev) = 0;
};

class CD3D11SomeClass : public ISomeClass
{
public:
virtual void foo(IDevice* pDev) override
{
// should only be passed CD3D11Device
}
};

class CD3D12SomeClass : public ISomeClass
{
public:
virtual void foo(IDevice* pDev) override
{
// should only be passed CD3D12Device
}
};

Я знаю, что могу позвонить dynamic_cast на IDevice* указатели каждый раз и проверьте nullptr но это утомительно и дорого с точки зрения производительности.

Есть ли какое-то элегантное решение этой проблемы? Кто-нибудь из вас знает, как профессиональные / коммерческие игровые движки справляются с этим?

1

Решение

Вы не сможете абстрагироваться D3D11 а также D3D12 вместе, если вы не идете намного дальше в абстракции, чем просто обертывание их интерфейса. Их конструкция слишком симметрична. Что вам нужно, так это спроектировать единый сильно абстрактный интерфейс движка рендеринга. Вещи как Material, Image или же Model должно быть строгое дно вдоль боковых вещей, таких как Scene или же RenderList,

Что касается поддержки нескольких графических API в одном приложении, то вы ошибаетесь, в этом нет смысла D3D11 Путь к коду, если у вас есть D3D12выбор должен быть D3D11/GL против D3D12/Vulkan, И это не из-за сходства API, а из-за набора функций, которые вам нужны в вашем приложении.

Потому что быть совет, D3D12 не предназначен для замены D3D11первые существуют для 1% приложений, таких как игры AAA или тяжелый GPGPU, для большого набора данных. Если вы не являетесь экспертом в D3D11 уже и не знаю, почему именно вы должны использовать D3D12не используйте его!

1

Другие решения

Других решений пока нет …