Public Interface
The public interface is comprised of all of the public, abstract types which are exposed from Veldrid. This includes the GraphicsDevice, the ResourceFactory, and all of the child resources the factory can create (DeviceBuffer, Texture, Pipeline, etc.). There are also a variety of enumerations and structures which are shared between the backends, but these are not abstract and do not differ in any way between the backends. In almost all cases, enumerated types correspond directly to an API-specific enumeration, and are translated very simply back and forth.
There are two primary functions of the public types: to define the interface accessed by user code (self-explanatory), and to enforce correct usage of the API. Because of the variety and complexity of graphics functionality provided, it is not feasible to validate every type of usage error within the type system. Instead, some required invariants are validated at runtime instead, to ensure that user code is not performing an impossible or illegal operation, or sequence of operations. For example: in order to use a DeviceBuffer as the source for vertex information, it needs to be created with the BufferUsage.VertexBuffer flag. The type system will permit any DeviceBuffer to be used in the CommandList.SetVertexBuffer method, but an error will be generated if the provided buffer was not created with that flag.
Another example: a Framebuffer can be created from any set of Texture objects, but there are additional requirements that cannot be validated in the type system. The depth attachment of a Framebuffer must have the TextureUsage.DepthStencil flag, and all color attachments must have the TextureUsage.RenderTarget flag. An error will be generated if this is violated at runtime. Additionally, all of the Textures in a Framebuffer need to have the same dimensions, because it is not possible to render to multiple Textures which are not the same size. If this is attempted, a different error will be generated.
Validation is performed in the public types because it ensures correct usage of the Veldrid abstraction regardless of which backend is in use. In reality, some invariants are not strictly necessary in some graphics backends, and no errors would occur when ignored in those backends. Up-front validation ensures that code written using Veldrid will still behave correctly regardless of which backend is used. For example, Veldrid requires that Pipeline objects declare the output Texture format that they will use. In the Direct3D11 and OpenGL backends, this information is not important -- those API's do not care about this and will accomodate any output format themselves. Modern API's, however, like Vulkan and Metal, are very interested in this information, and do not permit mismatched output formats to be used. Veldrid, therefore, validates this information up-front and in a generic way, to ensure that user code is not relying on the quirks of a particular backend to function properly.
These validation checks can be disabled with a preprocessor flag if desired (VALIDATE_USAGE
, enabled by default). This should be done once an application has been well-tested, and it is known that no usage errors are present. Although most checks are inexpensive (during one-time resource creation, for example), some usage checks can be quite costly, because they may be performed an extremely large number of times per frame, depending on how the API is used. Public releases of Veldrid always have validation enabled, to enforce usage correctness.
Some methods in the public interface are not abstract, meaning they do not need to be implemented by particular backends. These non-abstract methods are generally just "helper methods", which end up calling another method. For example, there are several CopyTexture overloads which copy different subregions of one Texture to another. These are provided for convenience, because often you simply want to copy the entirety of one Texture to another, and don't care to specify all of the individual dimensions. Ultimately, there is a single method implemented in each backend which handles all Texture copying.