General overview of how DirectX works?

Started by
5 comments, last by KMD 15 years, 9 months ago
Hey all, I've been browsing these forums for quite some time, and I've been reading up on DirectX 9.0c and have been a little bit confused about some of the ideas used, for example: devices/adapters, surfaces, formats, HAL/REF etc. and generally just the big picture, how does DirectX work by bringing all of these elements together broadly speaking? What does the "drawing" to what? If anyone can give me a general overview of how DirectX does its stuff, I would be forever grateful! As you can probably tell, I'm only just beginning to play around with DirectX. Thanks alot in advance!
Advertisement
The main component of D3D9 is the Device, which your app manipulates through the IDirect3DDevice9 interface. The device is pretty much in charge of everything to do with rendering. You give it textures/surfaces/shaders and tell it what to do with them, you tell it what you want to render to, and you tell it how things should be rendered. Ultimately all real drawing boils down to a "DrawPrimitive" call. There are a few "DrawPrimitive" methods for the device, and basically all of them are the equivalent of saying "hey I've got some triangles I want to render, draw them for me!". The device is also used to create all resources you use, like vertex buffers, index buffers, textures, etc.

A surface in D3D9 is really just a bunch of contiguous memory, usually used to hold pixel data. Every surface has a format, which specifies how that memory is laid out. for example a popular format is A8R8G8B8, which specifies that each pixel is made up for components that are 8 bits each (making32 bits per pixel). These format is important as it lets the device know how to read and write pixels to that surface. A surface is usually created as part of a texture. A texture is just a collection of surfaces, with each surface representing a level in the mip-map chain. Textures can be read by the pipeline when rendering primitives, for example to be used as the color of a surface. It's also possible to render to specially-created textures, which is actually done by rendering to the top-level surface (the device always renders to a surface).

HAL and REF refer to the two types of devices you can create. HAL stands for "Hardware Abstraction Layer", and uses the PC's 3D acceleration hardware to render primitives. REF is the reference rasterizer, and renders completely in software. The REF device is not meant to be actually used for released apps (it's not included in the consumer DirectX redistributable), instead it is mainly used to verify hardware or driver bugs.
You may also find Richard's The Direct3D Graphics Pipeline. From memory it has the first few chapters covering the general concepts and architecture details.

hth
Jack

<hr align="left" width="25%" />
Jack Hoxley <small>[</small><small> Forum FAQ | Revised FAQ | MVP Profile | Developer Journal ]</small>

Excellent, thank you. I'd probably want to look into IDirect3DDevice9 "devices" a little bit more, if thats the main D3D9 component.

A couple more questions regarding this:

1. Does a IDirect3DDevice9 device always render to a particular "surface", and is a "surface" analogous to the canvas that a painter would paint on?

2. Is there any particular "format" for depth/back buffers that are widely used for fullscreen and windowed mode? And does this format affect the way you 'do the DirectX stuff'? Is there a difference between the 'display format' and the 'back buffer format'?

I was reading a bit about all of these different formats and modes supported in the SDK, and when I checked out my own capabilities using the DirectX Caps Viewer utility, I was surprised to find my GeForce 8800 GTS only supporting D3DFMT_X8R8G8B8 (fullscreen and windowed) and D3DFMT_R5G6B5 (fullscreen and windowed). Am I missing something? Or even worse, is my graphics card broken!
edit: actually now I realise theres an 'adapter format' and a 'render format' and the render formats are compatible with many more formats. What's the deal with that?

edit: jollyjeffers - Thank you! I was reading through that a little bit earlier and had set it aside for some deeper reading when its not 2:48am :) It's a nice resource, I wonder if that has been published as a book yet?
Quote:Original post by KMD
1. Does a IDirect3DDevice9 device always render to a particular "surface", and is a "surface" analogous to the canvas that a painter would paint on?
Yes. A device always renders to the backbuffer associated with that device. The backbuffer is created with the present parameters passed to CreateDevice.

Quote:Original post by KMD
2. Is there any particular "format" for depth/back buffers that are widely used for fullscreen and windowed mode? And does this format affect the way you 'do the DirectX stuff'? Is there a difference between the 'display format' and the 'back buffer format'?
Usually D3DFMT_X8R8G8B8 for windowed and fullscreen modes is used. The only time that format matters is if you're reading from the backbuffer (E.g. for saving a screenshot). Then your code needs to know the format the data is coming in.
The display format is the format that the display is in, and the backbuffer format is the format the backbuffer is in. For fullscreen mode, they'll be the same, for windowed mode they may be different (You could have a 16-bit backbuffer but the desktop could be in a 32-bit mode).

Quote:Original post by KMD
I was reading a bit about all of these different formats and modes supported in the SDK, and when I checked out my own capabilities using the DirectX Caps Viewer utility, I was surprised to find my GeForce 8800 GTS only supporting D3DFMT_X8R8G8B8 (fullscreen and windowed) and D3DFMT_R5G6B5 (fullscreen and windowed). Am I missing something? Or even worse, is my graphics card broken!
That's quite possible. Those are the most common modes (32-bit and 16-bit). If the card supported more modes, it could potentially slow the card down, as it might have to do some conversion between types internally.
Quote:Original post by KMD
1. Does a IDirect3DDevice9 device always render to a particular "surface", and is a "surface" analogous to the canvas that a painter would paint on?


No, it doesn't. You can set which surface is currently being rendered to using IDirect3DDevice9::SetRenderTarget. In fact most DX9-class devices are capable of rendering to up to 4 surfaces simultaneously, using a feature known as Multiple Render Targets (MRT's).

Quote:Original post by KMD
2. Is there any particular "format" for depth/back buffers that are widely used for fullscreen and windowed mode? And does this format affect the way you 'do the DirectX stuff'? Is there a difference between the 'display format' and the 'back buffer format'?

I was reading a bit about all of these different formats and modes supported in the SDK, and when I checked out my own capabilities using the DirectX Caps Viewer utility, I was surprised to find my GeForce 8800 GTS only supporting D3DFMT_X8R8G8B8 (fullscreen and windowed) and D3DFMT_R5G6B5 (fullscreen and windowed). Am I missing something? Or even worse, is my graphics card broken!
edit: actually now I realise theres an 'adapter format' and a 'render format' and the render formats are compatible with many more formats. What's the deal with that?


For the back-buffer A8R8G8B8 is most commonly used. For the depth-stencil buffer, D24S8 (24-bit depth, 8-bit stencil) is pretty common. And yes there's a difference between the "display format" and "back-buffer format". Most graphics cards are very restricted in their display formats (like your 8800), since monitors can only take 16-bit or 24-bit input. Display format also never has alpha, since alpha is meaningless once you're displaying something on screen (alpha is only useful for blending things together). However the back-buffer typically does have alpha, as often times things are blended into the back-buffer (nothing is blended into the front-buffer, since you don't directly render to it).

It's worth noting that most modern games will render to many many surfaces (can be dozens, depending on the technique used) in order to accomplish a wide variety of visual effects. These surfaces may be various sizes and formats, depending on what needs to be accomplished. For example might render to multiple shadow-maps using a format like R32F, or might first render to a screen-sized A16R16G16B16F format for use with tone-mapping. Once all of this rendering to intermediate surfaces is done, the back-buffer is typically the last step. The app will copy all final results to the back-buffer, do any additional rendering, and then call IDirect3DDevice9::Present to say "hey I'm done with the back-buffer, display it on the screen!".
Thanks for the replies! I have alot of learning to do it seems :)
Suddenly, the world of DirectX seems so much more complicated!

This topic is closed to new replies.

Advertisement