简体   繁体   中英

Handing of C code in C++ (Vulkan)

I am trying to write a rendering engine in C++ based on Vulkan. Vulkan is written in C, as a result it has some interesting conventions.

A recurring pattern I see in tutorials/code snippets from Vulkan apps is that most code is in 1 very big class. (right now my vulkan class is already about 2000 lines too). But to make a proper rendering engine, I will need to compartmentalize my code till some degree.

One of the aforementioned interesting bits is that it has something called a Logical Device, which is an abstract reference to the graphics card.

It is used everywhere, to create and allocate things in the following way:

  1. Create structs with creation info
  2. Create variable that the code will output into
  3. Call the actual vkCreateSomething or vkAllocateSomething function, pass in the logical device, the creation info and the reference to the variable to output to and check if it was a success.

on its own there is nothing wrong with this style I'd say. It's just that it's not really handy at all in OOP because it relies on the logical device being available everywhere.

How would I deal with this problem? Service locators and singletons are considered to be horrible solutions by many (which I can understand), so that seems like something I'd rather avoid.

Are there design patterns that deal with this?

The logical device is an actual dependency.

It has state, and its state needs to be available to work with the hardware.

You can use it as an argument to your operations, a value stored in pretty much every class, a global, or a monadic-esque "final" argument where every operation just returns something still needing the device to run on. You can replace a (pointer/reference to) it with a function returning a (pointer/reference to) it.

Consider if pure OOP is what you want to do; vulkan and rendering is more about operations than things being operated on. I would want to mix some functional programming patterns in, which makes the monad-like choice more reasonable.

Compose operations on buffers/data. These return operations, which also take buffers and data. The composition operation specifies which arguments are new inputs, and which are consumed by the next step. Doing this you can (at compile time) set up a type-safe graph of work to do, all without running anything.

The resulting composed operation would then have a setup (where you bind the logical device and anything you can do "early" before you need to have the expensive buffers ready), and an execute phase (where you feed it the expensive buffers and it generates output).

Or as another approach, find a compiler with coroutine support from and write it async yet procedurally.

Vulkan is a OOP API. It is not class-based, because it is C99 not C++. That can easily be fixed by using the official Vulkan-Hpp . You can consume it as vulkan.hpp which is part of the semi-official LunarG Vulkan SDK .

The usage would not be that different from vulkan.h though: you would probably have a member pointer/reference to a Device instance, or would have a VkDevice handle member in each object that needs it. Some higher level object would handle the lifetime of the Logical Device (eg your RenderingEngine class or such). The difference would be almost only esthetical: you would use device->command(...) instead of vkCommand(device, ...) . vulkan.hpp does not seem to use proper RAII through constructors/destructors which is a shame.

Alternatively the user of your engine can manage the device. Though unlike OpenGL there is not much use for this. The user can make its own VkInstance and VkDevice if it also wishes to use Vulkan for something.

A recurring pattern I see in tutorials/code snippets from Vulkan apps is that most code is in 1 very big class.

That's not really specific to Vulkan. If you think about it, pretty much all C++ applications are one big class doing everything (only differences being how much the programmer bothers to delegate from it to some other class instances).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM