Shawn Hargreaves Blog
I was relieved when the comments on my earlier post about backward compatibility agreed with the approach we chose for XNA Game Studio 4.0. Banjobeni summed up the general sentiment:
"If you break it, break it good."
"If you break it, break it good."
The initial motivation for breaking changes in XNA GS 4.0 was the addition of Windows Phone, but this is about more than any one platform. A quick history lesson:
Version 1.0 of the XNA Framework was designed around DirectX 9 on Windows. We had little time to create an enormous API, so had to move fast and decisively. In retrospect I think we did a great job choosing the right places to concentrate our design efforts, and I’m proud of what we built, but there were many areas where we decided “hey, we don’t have time to agonize over this detail, so let’s just copy whatever native DirectX 9 does, and move on”.
When we started work on Xbox 360 in the second half of the 1.0 development schedule, some of these hasty decisions needed to be revised (and some were revised further in our 2.0 release), but many were left alone. Even when things didn’t exactly fit the Xbox, they were similar enough that we could squint and say “yeah, that’s close enough to get the job done”.
When we looked at the new phone platform, we found more things that did not work quite the same as on Windows. Had we tried to squint until they looked the same, we would have ended up with our eyes screwed most of the way shut! I’m a perfectionist, and that just didn’t feel good enough.
Ok, let’s change our API in the places necessary to make the phone consistent with our other platforms.
But breaking changes are expensive. Having gone three years without any major breaks, we felt this was a good time to introduce an inflection point, cleaning up our act and setting ourselves up for the future. But we also felt it was important that this be a one time thing. Breaking changes every three years may be ok, but every year, or every six months, most certainly would not. If we’re going to break it, let’s break it good, taking all the pain in one go so we don’t have to break again for many years to come.
So, we took the opportunity provided by the phone to also reduce those nagging Windows vs. Xbox inconsistencies.
We also used this opportunity to improve usability, applying our three years of experience to look at which things cause the most confusion for our customers, and tweaking these APIs to reduce the chance of error.
Finally, we gazed deep into our crystal ball in an attempt to predict the future. This failed miserably (sadly, it turns out I am not psychic at all :-) so instead I made some guesses. XNA Game Studio 4.0 sits on top of DirectX 9 on both Windows and Xbox 360, and we have no immediate plans to move to DirectX 10 or 11, but looking years into the future, it seems at least possible we might someday want to do that. DirectX 11 adds some things that are not in DirectX 9, but it also changes and in some cases removes features. Adding features is relatively painless from a compatibility perspective (it’s easy to imagine how a third profile could someday sit alongside Reach and HiDef) but taking things away hurts deep (it would suck if any such third profile could not be a strict superset of HiDef, in the same way that HiDef is a superset of Reach). So we looked at what it would take to implement our API using DirectX 11, and made sure we didn’t include anything that would make this excessively difficult. I am not promising we will ever support DirectX 11, just saying we did some thinking about this and laid some groundwork so if we ever do want it, we can go there without having to break backward compatibility.
An overarching goal of these API tweaks was that even though we are breaking things, we still want the new API to feel like the XNA Framework you know and love. Some of the details may be different, but existing developer knowledge and design patterns should be easy to move across.
Another goal was to prefer simplicity over complexity. I am a big believer in minimalist design. It’s easy to add new things each time we encounter a new problem, but I think more valuable to hone them down to their core essence, trying to find the minimum surface area necessary to communicate between developer and runtime. It makes me happy that the XNA Framework 4.0 API surface is significantly smaller than the 3.1 version.
I’ll be writing more about these changes and the reasons behind them over the coming weeks, but here is a quick summary of the more significant breaking changes:
I suspect some of you will have concerns about some of these removals. Don’t panic! This article is already too long, and I’m running out of time to write more, but I am confident once I explain the why, how, and wheretofore of these changes, you will agree they are good and sensible. If there are specific things you would like me to write about first, please let me know via the comments below.
Thanks shawn for the info,,but
1 .Each rendertarget now has an associated depth buffer: no more DepthStencilBuffer type
this meen that if we are on the xbox360 we can use the full 10mb special ram , course there will allways an underlying depthbuffer, in place
2.RenderTarget2D now inherits Texture2D: no more GetTexture method
Do we have custrom resolve from a lover rendertarget to a higher texture resulition
3. when are we gonna test out the HiDef version of the Framework
Great post, as usual. I have to say I was a bit concerned at first when you talked about Reach vs. HiDef , this post however makes me feel like the changes will be a lot better.
I do have a few questions though about the list of changes, although I assume they will come with the post about each of them individually, so these are the posts I, personally, would like to hear about first:
1) "Removed the low level shader APIs (VertexShader, PixelShader, Set*ShaderConstant)"
2) "Removed point sprites"
3) "Replaced Effect.Begin and End with a new EffectPass.Apply method"
To be honest I don't have any questions about the third, it juts sounds like a really good idea and I would like to hear more about it.
Either way, sounds like you've done more than just a great job with GS 4.0.
ResolveTexture2D also seems to have vanished, aswell as graphicsDevice.ResolveBackBuffer. Might be worth noteing.
I'm developing for Windows, so the obvious question to your post here is: will the GS4.0 make it harder for me? I do use a lot of low-level API's (as far as you can call any part of XNA API low-level) so are these changes more into making API more clean and consistent across framework or it's more about removing features that YOU think most people won't use anyway so why bother?
How about performance of GS4.0 vs. GS3.1 - how much overhead new usability changes will introduce if any?
There is only one I am really concerned about, and that is the removal of clip planes. Sure it may be some future proofing, but right now popular techniques simply rely on it, such as planar reflection.
"RenderTarget2D now inherits Texture2D: no more GetTexture method"
that makes me glad. I had a heck of a time trying to figure that one out when all the posts on the forum I could find about it seemed to be from back in 1.0 and some other things had changed in that time
As for me, I'm interested in how to work around the removal of point sprites. In my game, I have hundreds of thousands of particles and using point sprites allowed me to quickly pass in the data needed to render them. Though I was also looking into geometry shaders to do these, which would even allow non-square particles, but since there's no directx10 or 11... I know I can use spritebatch or make my own triangles, but aren't point sprites faster?
I like some of the concepts present in this release but... and I don't want to sound ungrateful or whiney here, but please don't oversimplify the API. Just because collapsing the caps and combining alpha renderstates makes it easier for new developers, some of us really want the level of control that comes with the more diverse option set and losing that functionality could push us away.
On a more positive note, once I got used to the EffectPass.Apply change, I really started to like it. And the RenderTarget and VertexBuffer changes sound awesome. Kudos to the whole team!
> I'm developing for Windows, so the obvious question to your post here is: will the GS4.0 make it harder for me?
Not at all! In fact I think they will make it easier, as you will not have such a difficult time making your game compatible across different PC's.
Ultimately, though, you'll have to judge this for yourself :-)
> How about performance of GS4.0 vs. GS3.1 - how much overhead new usability changes will introduce if any?
Mostly they make things faster, as they move much validation logic from draw time to create time.
> There is only one I am really concerned about, and that is the removal of clip planes.
Clip planes can be implemented quite easily in a shader (like they are in DX10+), and this will perform just as good as using the older dedicated API (in fact many DX9 drivers implement them by patching shaders to add clip instructions).
This does mean you don't get clip planes on the phone (no custom shaders there), but then, you wouldn't have gotten them anyway since there is no fixed function clip plane hardware either!
> As for me, I'm interested in how to work around the removal of point sprites.
Heh, yes, I was expecting some questions about this!
The motivation for this removal was obviously that there are no point sprites in DX10 or 11, but we too were pretty worried about this. It would be bad if something like the 3D Particle sample was no longer possible, or decreased in performance!
Short answer: don't worry, it's fine, turns out point sprites aren't so great for performance even on hardware that does support them, and we actually managed to make the 3D Particle sample run FASTER on Xbox by changing it from point sprites to triangle lists!
Longer answer is somewhat subtle and full of details that deserve a post of their own. Stay tuned...
> Just because collapsing the caps and combining alpha renderstates makes it easier for new developers, some of us really want the level of control that comes with the more diverse option set and losing that functionality could push us away.
I would love to hear more about which specific options you are worried about losing?
I'm pretty confident that once you see where things have moved, or what alternative ways exist to replace the things we removed, you'll see that all the neccessary abilities are still very much present.
These changes were about simplification for sure, but not just for new developers and not at the cost of removing important features that people need!
Sounds great - my experiences with point sprites, vertex declaration tricks, and render target resolving often turned out to work only when bent to the will of a specific graphics card, destined to fail on nearly any other machine. The framework will be better for the removal/simplification of them.
One red flag was raised: "Each rendertarget now has an associated depth buffer: no more DepthStencilBuffer type"
As mentioned, this could have some negative performance issues with the Xbox 360's 10MB eDRAM. It also increases the memory usage for some shadow mapping techniques and other off screen rendering methods that don't require a depth buffer. That could be resolved by specifying that a render target has no associated depth buffer, but a lack of depth buffer sharing could affect other rendering configurations, like deferred lighting.
Kudos on the changes, though. A few carefully placed constraints prevents so much pain down the road, and encourages more productive game crafting.
How do the vertex buffer changes affect support for hardware instancing? (on windows, I assume vfetch is still possible on 360).
I have a lot of instanced geometry and my framerate would be terrible without instancing support...
"# Vertex buffers are now strongly typed, each one having an associated VertexDeclaration
# You no longer need to specify a VertexDeclaration before drawing, because this is implicit in your choice of vertex buffer
# Vertex buffer sizes are now specified as number of vertices rather than bytes "
Thank you (plural you) for this. I always found it as a failure to leverage the OO from C# that this wasn't done.
The removal of clip planes concerns me as well. I rarely use shaders, relying on BasicEffect for most of my work, but I need ClipPlanes for my portal system. They were so simple to use; now you're saying "We're taking that out, so you have to make it yourself". Isn't the reason I'm using XNA is so I don't have to make it myself for such simple things?