Jump to content
  • Advertisement
  • entries
  • comments
  • views

The SlimDX Architecture, Part 3

Sign in to follow this  


I asked Josh to write up a follow up to the first two parts, covering the ancillary object support in our ObjectTable, which he graciously agreed to. Here it is.

I want to switch gears a little bit and talk about a class you've almost certainly seen if you're doing any SlimDX work: DataStream. I'd describe ObjectTable and ComObject as the heart of SlimDX, and DataStream as the soul. It's been exceedingly difficult to get right, with 41 revisions of the header and 50 revisions of the source, even though the feature set has only changed a little bit over time. In fact, we just changed it again. It's critical to most people because it does the one thing everybody needs to do -- transfer data from the application to the API, and occasionally vice versa.

The original class in MDX was called GraphicsStream, and SlimDX used the same name for a while. We decided in r138 to rename the class to DataStream, since it was fairly obvious that it wasn't graphics-specific in any way. The name was never quite ideal, but MemoryStream is taken and we couldn't figure out something better. Besides, it's kinda catchy. Although the goal of the class was kind of vague at first, it fundamentally represents what a pointer has become in managed code. It's not quite as elegant in many ways, but unlike a pointer it is a hell of a lot safer.

The DataStream typically replaces a pointer in the underlying API, but a pointer in the unmanaged world is a relatively simple beast. In the managed world, we have a whole host of problems. There's a few different places that a user could want to copy data to or from:
  • An array on the managed heap

  • A managed Stream

  • A buffer on the native heap (owned by anybody)

  • Memory in an ID3DXBuffer

In XNA, the approach to handling this complexity is to dispense with it entirely, and limit data transfers to managed arrays only. I criticized this decision heavily when the beta was released, but it's not necesarily an unreasonable one. I just didn't think it was the right move. It does fit in with the overall design strategy of XNA, after all. However, it doesn't fit the SlimDX design philosophy, so we have a somewhat different approach.

DataStream can do all of these things. That's why the name is so vague; trying to quantify the class at all is difficult. It exists to mediate data transfer between an application and DirectX, in either direction; it provides the standard Stream interface. Every DataStream has a backing store that can be stored in a pointer, but sometimes there's auxiliary members. (A pin handle or an ID3DXBuffer are currently supported.) You can even allocate memory off the native heap for use via one of the constructors, in case that's useful.

DataStream's code is very simple and easy to understand, but it's fraught with subtleties. The bounds checks have to be exactly right, which has been surprisingly difficult to do. It's also important to use the correct pointer; sometimes this is the beginning of the stream and sometimes it's the stream position. Despite those pitfalls, it's not a class that looks threatening...but it does power nearly all of the data transfer in SlimDX.
Sign in to follow this  


Recommended Comments

There are no comments to display.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!