Monday, January 11, 2010

Upcoming changes for the beta release

It won't happen for a while yet as some of the changes required involve a massive tidy-up job on the renderer. Right now, if you've looked at the source code, you'll notice that I have multiple versions of what is broadly the same code handling HLSL water, non-HLSL water, sky, solid surfaces and maybe a few other things. These all need to be integrated into a single path. The core concept of the renderer is quite solid but I'm going to be maintaining this code for the foreseeable future and the implementation is not quite up to scratch in general tidiness.

The current plan, in addition to integrating the paths, is to maybe avoid the memory copy operation I have by writing to a write-only dynamic Vertex Buffer instead. Vertex Buffers are normally not quite suitable for situations where geometry (and vertex data) changes on a frame-by-frame basis, but I think that this time round I can obtain benefit from use of one. Unfortunately here's where D3D's somewhat arbitrary-seeming usage restrictions are going to bite as I need to create it in the Default memory pool, meaning that it needs handling conditions set up for device loss. Yuck. Still, it should mean something of a performance boost.

However, experience has taught me that locking, filling, and using the same resource multiple times per frame is a guaranteed recipe for quite severe performance penalties, so two approaches spring to mind, the first of which is to use a really really really big vertex buffer, and maintain offsets for each use of it; while the second is to have a pool of smaller vertex buffers that is cycled through. On balance I wonder if the complexity is worth the effort, especially for world surfaces where fillrate and overdraw are larger bottlenecks than vertex submission. It seems worth a try for alias models however.

Speaking of vertexes, a bug has surfaced where some drivers do not respect the vertex stride parameter they are given during a rendering call. What's the point of even having a stride parameter if respecting it is optional? Sigh. Anyway, in some cases I use a stride larger than the FVF becuase either (a) I was lazy and didn't feel like creating a new vertex type at the time, or (b) I needed to cache some extra data that wasn't used during rendering but that was needed for set up. End result is that for cases where I might have an FVF of xyz/diffuse but a vertex layout of xyz/diffuse/other-data, and I specify the correct stride for the vertex layout, the driver ignores it and works off the FVF instead, resulting in the values in the "other data" members being used for (at least part of) the xyz for the next vertex. This generally happens for draw operations that retained the old 1.7.x and earlier code, like the 2D stuff (including the underwater warp), primarily. Not too difficult to fix, but annoying all the same.

I'm thinking of dropping support for the fixed pipeline path entirely. Complexities came in from requiring to support it for water surfaces where a totally different and non-compatible vertex/index layout was required (owing to surface subdivision) and it's just going to make things fiddly and awkward going forward. That doesn't mean that a full-blown HLSL-on-everything path is going to come back, but it does mean that the two surface types where there is currently a HLSL or fixed option (sky and water) might drop the fixed option.

I wonder if there is anything still in reasonably common use that doesn't support at least Shader Model 2.0? Even Intel GMA900 stuff supports it.

MAX_BEAMS has gone up to 29,125. Now if you need almost thirty thousand lightning bolts flying around in a map you will be able to have them.

Update/addendum: did I say 29,125? I meant 29,127 of course. Those extra 2 bolts might be crucial...

0 comments: