Discreet 3D Studio MAX was the first shipping Heidi application. As such, there is industry-wide interest for writing Heidi drivers to accelerate 3D Studio MAX. This appendix is an article originally written in 1998 by Don Brittain of the Yost Group. It is still relevant and provides an overview of important issues when implementing Heidi drivers for 3D Studio MAX and 3D Studio VIZ.
Yost Group
The information in this article pertains to 3D Studio MAX release 3.1 and 3D Studio VIZ through release 3.0. Both use Heidi 6.0.
But there are several ways in which
the MAX approach differs from the traditional text-book pipeline. In fact,
in the MAX context "graphics pipeline" is a misnomer, because there is
really a lot of two-way communication, rather than a bunch of data flowing
one direction down a display pipe. In the MAX graphics model:
Display Buffers
First, with regard to resource allocation, MAX is a pig. Not only does each viewport need a front and back image buffer, and a Z buffer, but (with dual-planes turned on) MAX also needs an extra image buffer and an extra Z buffer to cache the viewport display.
MAX uses these cache buffers to avoid having to re-render an entire scene when only a subset of the objects in the scene change. In almost all real life situations, this results in substantial gains in interactivity for the user, and thus this plays a central role in the MAX display architecture.
But because buffer readback (reading the real image or Z buffer into one of the cache buffers) always requires the transfer of the entire buffer (that is, not a rectangular subset), this operation can be a real bottleneck on some systems. In particular, if the cache buffers do not fit within the memory space of the graphics display card, then the readback operation is limited by the system bus bandwidth.
MAX usually doesn't try to interpret the readback caches in any way. Rather, the caches are simply "blitted" back to the real image/Z buffers at some later time. (Actually, usually only a rectangular subset of the caches are blitted. And the same subset is used for both the image and Z buffers.)
This means that readback data does not usually have to be converted into any standard color formats - whatever is quickest for accomplishing the readback and blit operations within the driver itself is what is best for MAX. Under these circumstances, MAX will request image data from the driver by way of the HT_Image_Format::any descriptor.
Note: In those cases where MAX does need to be able to interpret the image data, as when creating an AVI or QuickTime file, MAX will request a specific color format from the driver.
As a small consolation for using so much display memory, MAX does not allow the user to overlap the viewports in the main MAX window. And if nothing in the display is depth-buffered, then the Z buffer is not readback or blitted.
The size of textures handed down to Heidi are user selectable as either 64, 128, 256, or 512 pixels square.
Also, even when rendering a depth-buffered scene, MAX often turns the Z buffer on and off. This is because the coordinate system axis display and the viewport labels are never Z buffered. Thus, it is important to optimize the toggling of this state.
On the subject of depth-buffering: MAX never asks Heidi to rasterize non-depth-buffered filled primitives. So, there is no need to even implement those primitives – just kick them back up to the higher level Heidi routines because they won’t be called by MAX anyway.
Multi-threading
MAX is highly multi-threaded. To synchronize
input, each viewport has a transparent window above it owned by the main
MAX thread. So no input comes to the Heidi window.
Also, each Heidi window has one thread to execute (possibly asynchronous) window procedure calls, and another thread to execute Heidi rasterization calls. Almost all driver calls are executed asynchronously from their request in the higher-level MAX code through a queuing mechanism inside MAX. This can make debugging a Heidi driver a bit of a challenge. So, it is possible to build a non-client/server version of MAX to aid in this regard. As long as all driver calls are fully re-entrant, a driver that is completely debugged in "single processing" mode should continue to work reliably in "multi-processing" mode.
Finally, MAX uses an algorithm to limit the amount of any viewport that is invalidated and blitted during each display update. This means that MAX may not correctly update a viewport display if the user slides the MAX window off the screen and then slides it back on screen. Although this is not optimal, we decided that the speed benefits we obtain from the limited redraws during normal MAX operation far outweighed the loss during this uncommon move, and so we simply require that the user force a display redraw at that time.