docs

GPU Device Capabilities

Report optional GPU features and device limits to the renderer.

On this page

You can report optional hardware features and device limits to the renderer when implementing a custom GPU driver. This lets the renderer use capabilities like multisampling and compressed textures while staying within hardware boundaries.

Drivers included with AppCore already report their capabilities— you only need to set them when providing a custom driver.

Reporting Capabilities

To report device capabilities, override GPUDriver::GetDeviceCaps() and set the fields for the features the hardware supports:

C++
#include <Ultralight/Ultralight.h>

using namespace ultralight;

class MyGPUDriver : public GPUDriver {
 public:
  void GetDeviceCaps(GPUDeviceCaps& caps) override {
    ///
    /// Our device samples both block-compressed families in hardware.
    ///
    caps.compressed_formats =
        kGPUCompressedFormat_BC1_BC3 | kGPUCompressedFormat_BC7;

    ///
    /// We can allocate multisampled render targets, four samples each.
    ///
    caps.supports_msaa = 1;
    caps.max_msaa_samples = 4;

    ///
    /// The largest width or height our device can create (ask your
    /// graphics API).
    ///
    caps.max_texture_dimension = 16384;
  }

  // The remaining overrides are covered in Implementing a GPUDriver.
};

The renderer passes a zero-initialized structure when it first needs device capabilities. It may cache the result— reported values must remain unchanged for the lifetime of the process.

If a driver does not override GetDeviceCaps(), all fields remain zero. The renderer continues to operate normally with optional features disabled and conservative default limits.

Field Kind Default When Zero
compressed_formats Capability No compressed formats supported (the renderer decompresses textures to BGRA before upload)
supports_msaa Capability Single-sample render targets only
supports_partial_redraw Capability Full redraw of the View target on every composite
max_texture_dimension Limit Not reported (the renderer uses a built-in default)
max_msaa_samples Limit Not reported (the renderer uses a built-in default)
max_geometry_size Limit Not reported (the renderer uses a built-in default)

A zero value for a limit field never means that no resources are allowed— the renderer substitutes a safe built-in default instead.

Configuring Multisampling

Set supports_msaa to 1 when the driver can allocate multisampled render targets, and set max_msaa_samples to the sample count so the renderer can account for texture memory.

The driver receives the kGPUTextureFlag_Antialiased flag in GPUDriver::CreateTexture() only when supports_msaa is set and analytic rendering is turned off. Analytic rendering (Config::enable_photon) defaults to true and performs antialiasing directly in shaders without allocating multisampled targets.

Report multisampling support whenever the hardware supports it, even when analytic rendering remains active.

Enabling Partial Redraws

To enable partial redraws for View render targets, set supports_partial_redraw to 1 in GetDeviceCaps():

C++
void GetDeviceCaps(GPUDeviceCaps& caps) override {
  ///
  /// Redrawing part of a target costs only that part on this GPU.
  ///
  caps.supports_partial_redraw = 1;
}

This instructs the renderer to redraw only the modified regions of a View's render target on each composite. Enable this when redrawing part of a large target costs roughly what the drawn area costs.

Leave this capability set to 0 on tiled or bandwidth-constrained GPUs, where reloading previous contents costs as much as a full redraw.

🚧 Preserve Render Target Contents

The renderer performs partial redraws on tile render buffers across all drivers regardless of this setting. A driver must preserve render target contents between draws without discarding them on bind, and must support sampling from an existing render texture.

Supporting Compressed Formats

Set compressed_formats using a bitmask of GPUCompressedFormat flags to advertise the block-compressed formats the device supports.

When a flag is set, GPUDriver::CreateTexture() receives textures in that family for direct hardware sampling— unset formats are decompressed to BGRA before upload.

Flag Formats
kGPUCompressedFormat_BC1_BC3 BC1, BC2, and BC3 (DXT1, DXT3, DXT5)
kGPUCompressedFormat_BC7 BC7

Compressed textures require a Pro edition or higher. For instructions on loading and uploading compressed assets, see Compressed Textures.

Setting Hardware Limits

Set max_texture_dimension to the maximum width or height of any texture or render target the device can create. The renderer guarantees that no requested texture will exceed this dimension.

Set max_geometry_size to the largest buffer size, in bytes, for a single vertex or index buffer. If tessellating a vector path produces geometry that exceeds this limit, the renderer drops the path instead of attempting to upload it.