GraphicsAPI reference
Namespace MicroEngine.Graphics.Devices
The graphics device contract every backend implements: capabilities and the typed capability error, textures, render targets, samplers, buffers, pipelines, command lists with passes, readback and the surface target; the core validation backends inherit and the CPU reference device.
Guide: The graphics device
Classes
Fixed-function blending: result = src·SrcFactor (op) dst·DstFactor, separately for colour and alpha, computed
in float and quantised to the target format. The presets assume premultiplied colours.
A list of commands for one device, recorded on the render thread and validated here, in core, as it is recorded (before any backend sees it). Every violation throws at the call that causes it:
- a resource of another device: `ArgumentException`; a disposed one: `ObjectDisposedException`;
- wrong nesting (pass in a pass, draw or binding outside a pass, update inside a pass, recording after submit): `InvalidOperationException`;
- a pipeline whose attachment formats differ from the pass's, a draw without the bindings the pipeline needs, a range outside a buffer, sampling the pass's own colour target: `InvalidOperationException` or `ArgumentOutOfRangeException`;
- an undeclared capability (instancing): [GraphicsCapabilityException](/docs/api/microengine.graphics.devices.graphicscapabilityexception/).
Rules: commands execute in recording order (an update affects only draws recorded after it); bindings, pipeline, viewport and scissor are pass-scoped (each pass starts with none bound, the whole target as viewport and no scissor); uniform data persist for the rest of the list once set.
A shader compiled ahead of time from one HLSL source into every format a tier-1 device may accept (DXIL for
Direct3D 12, SPIR-V for Vulkan, MSL for Metal), with the resource counts reflection found. It is what
microengine shaders writes (one .shader file per HLSL file) and what a game ships: nothing compiles at
run time. DescriptionFor picks the format a device should be given; a device without custom shaders
gets the typed GraphicsCapabilityException, as for any undeclared capability.
A readback whose pixels were copied when it was requested (devices that execute at submit).
A vertex and/or index buffer.
What a device declares. Read after creation: the backend identity is what the device reports, not what was requested.
The one typed error for a missing capability: names the operation, the device and what it lacks. Thrown at creation or recording time, never deferred to a draw.
The graphics device contract this assembly implements. The contract text is the XML documentation of the types in
MicroEngine.Graphics.Devices; every rule it states is checked by the device conformance suite. A change to a
rule or to the shape of a type is a contract revision: it raises Version and records its evidence.
Core half of every device: validates each call against the written rules and the declared capabilities, then hands
the backend a call it can execute. Backends derive from it and implement only the *Core members, so ownership,
disposal, ranges and capability errors behave identically on every tier.
Device creation options.
Limits. Each value is a guaranteed minimum: a backend that cannot query its API reports the minimum the API specification guarantees, so a limit may be conservative but never optimistic.
Base of every device object. A resource belongs to the device that created it: using it with another device is an
ArgumentException, using it after Dispose an ObjectDisposedException, both
raised by core validation before a backend sees the call. Every resource has a Handle with a
generation: once the resource is disposed the handle no longer resolves
(TryGetResource``1), even if its slot is reused. Destruction is deferred: the
backend object is released only when no submitted work uses it any more (at once on devices that execute command
lists at Submit).
A custom pipeline: requires Shaders. The pipeline is bound to the attachment formats
it renders to: a pass accepts it only when its colour format equals ColorFormat and its depth
attachment format equals DepthFormat (null = the pass has no depth attachment).
A graphics pipeline: built-in (device-owned) or custom.
Conversions between 8-bit colours and the premultiplied float colours of the device contract.
An asynchronous read of a render target region, completed by a fence. The data are the pixels of every command list submitted before ReadPixels: rows top to bottom, tightly packed, in the target’s colour format.
ReferenceGraphicsBackendFactory
Factory of the CPU reference device (“reference”): offscreen, or over any surface (it never touches the window).
The CPU reference device: a tier-0 implementation of the graphics device contract that executes every written rule literally, in managed code, the same on every machine. It is the oracle the device conformance suite holds backends to and the device headless runs draw with. It favours clarity over speed.
A colour attachment (plus optional depth) that passes render to. Offscreen targets come from CreateRenderTarget and can be sampled through Color and read back. The surface target comes from TryAcquireSurfaceTarget, is valid until the next Present, cannot be sampled and cannot be read back.
Device-owned, cached sampler object for one SamplerDescription (never disposed by callers).
A custom shader stage.
Byte-size rules of texture formats, shared by validation and backends.
A texture that pipelines sample.
Interleaved vertex layout of one vertex buffer (slot 0).
Structs
A buffer, available on every tier (tier 0: device-owned CPU memory submitted to the backend’s geometry call; tier 1: GPU memory). Contents are written only by UpdateBuffer and are undefined until written.
The colour attachment of a pass.
One validated command, as a backend reads it from Commands.
The depth attachment of a pass: the depth texture of a target created with Depth.
Depth test and write. Depth is 0 (near) .. 1 (far); anything but None requires DepthBuffer.
Deterministic counts of the work a device received (Counters): the same calls give the same counts on every backend and every run, so tests can assert draw calls, passes and uploads exactly as a performance budget. Every count is cumulative since the device was created; subtract two readings to measure a span.
A render pass: one colour attachment and an optional depth attachment (several colour attachments are a later, additive extension). Viewport and scissor start as the whole colour target; bindings start empty.
Rasterizer state. Scissor is not here: it is dynamic pass state, always on (SetScissor).
An integer rectangle in pixels: origin top-left, x to the right, y down; right and bottom exclusive.
An offscreen target: one colour texture that can also be sampled, and an optional depth(-stencil) texture.
Immutable sampler state, a value: GetSampler returns a cached device object for it.
Sampling is never texture state. Min different from Mag requires
SeparateFilters. Mip applies only to textures with more than one
mip level and is otherwise ignored (so LinearClamp works on every tier).
Bytecode (or MSL source) of one shader in one format, with its entry point.
A custom shader; requires Shaders and a Format in ShaderFormats.
Resource counts of a shader, produced by the offline tool’s reflection and validated at creation. Bindings follow the SDL_GPU register-space rules (vertex uniforms space1; fragment samplers space2, fragment uniforms space3).
A sampled texture. Texture data uploads go through CreateTexture and UpdateTexture.
The vertex of the built-in pipeline (Textured), 32 bytes: position in target pixels relative to the viewport origin (y down), texture coordinate normalised to 0..1 over the bound texture, premultiplied colour that multiplies the texel. The layout is fixed and identical on every tier: Vertex2D.
One vertex attribute.
Interfaces
Creates devices of one backend. A backend that accepts only its own surfaces says so through UnsupportedReason.
The single graphics device contract for every tier. Tiers differ only in Capabilities; a request outside them throws GraphicsCapabilityException at creation or recording time.
Ordering rule: command lists execute in [Submit](/docs/api/microengine.graphics.devices.igraphicsdevice/#MicroEngine_Graphics_Devices_IGraphicsDevice_Submit_MicroEngine_Graphics_Devices_CommandList_) order, and within a list in recording order (updates included); [ReadPixels](/docs/api/microengine.graphics.devices.igraphicsdevice/#MicroEngine_Graphics_Devices_IGraphicsDevice_ReadPixels_MicroEngine_Graphics_Devices_RenderTarget_MicroEngine_Graphics_Devices_RectI_) observes every list submitted before it.
Threading: one thread (the render thread) creates, records, submits and presents.
Enums
What sampling does outside 0..1.
How the colour channels of texel data relate to alpha.
Blend factor (the set every tier-0 and tier-1 backend can express).
Blend operation.
Buffer usage. Uniform data is not a buffer: it is pushed with SetUniforms.
The built-in pipeline every tier implements with every blend state of BuiltInBlendStates: Vertex2D vertices, one texture in slot 0, no uniforms, no depth and no culling; colour = sample(texture) × vertex colour.
Kind of a recorded command (backend-facing; see Command for the fields each kind uses).
Depth comparison.
Face culling.
Why a device was lost.
Texel filter.
Front-face winding in framebuffer space (y up in clip space). The engine convention is counter-clockwise.
Optional features. Everything not listed here is mandatory on every tier: textures (Rgba8Unorm sampled and rendered), samplers with clamp addressing, buffers, the built-in pipeline with the four blend presets, scissor, viewport, readback and the surface target. A request that needs an undeclared feature fails with GraphicsCapabilityException naming it; there is no silent degradation.
Capability tier. Tiers differ only in declared capabilities, never in API shape.
Index element size.
What a pass does with an attachment’s previous contents.
When Present waits for the display.
Offline-compiled shader bytecode formats (produced by the tool from one HLSL source).
Programmable stage.
What a pass does with an attachment’s contents at its end.
Texel formats. Whether a format can be used for a purpose is a per-format, per-usage capability: Supports (depth formats in particular differ between adapters: AMD Vulkan has no 24-bit depth). Using an unsupported combination throws GraphicsCapabilityException.
What a texture of a given format may be used for; queried per format.
Vertex attribute element format.