I just tried to use four render targets on my Xbox 360 and it failed!!

Dear Mr Miller, you suck.  I’m running in 1080p resolution, and needed to have four simultaneous render targets, and a depth buffer, and I can’t do it.

Now, to be fair, I didn’t actually receive a message like that, but I could see it happening (and I’ve gotten some similar).  One of the features that we added this last release was the ability to use multiple simultaneous render targets on Xbox (up to four of them).  However, this isn’t without restriction.  All render targets that will be used on the device need to fit within the EDRAM (a 10MB chunk of memory). This includes the depth buffer if it exists.  EDRAM isn’t very big at all.

Let’s take a look at an example.  Your Xbox is rendering in wide screen 720p mode with a resolution of 1280×720.  You set your game to run at this exact same resolution with a surface format of Color (32bits) and a 32bit depth buffer as well.  You also turn on 2x multisampling because you hate jaggies like the rest of us.  All of this data needs to fit into EDRAM, so let’s see how big we are.  Each pixel in the back buffer will be 8 bytes (32bit for color, double it for multisampling).  There are 1280×720 pixels, so the back buffer will be taking up approximately 7.3MB of memory.  The depth buffer is the same size, so that’s another 7.3MB, and we’re looking at a total of almost 15MB of data we need to store in our 10MB chunk of memory.

As you can see, even this simple scenario we overstepped our bounds.  Luckily, we have a mechanism (called “tiling”) that allows us to work with this data anyway.  We essentially break our large 1280×720 set of pixels into a series of smaller sets of pixels that *do* fit within the memory constraints.  In the example above, the back buffer could be broken down into two separate “tiles” of size 640×720 with 2X multisampling, and things would work just fine.  With only two possible consumers of this chunk of memory in version one (the back buffer and the depth buffer), you could easily fit the largest possible back buffer sizes within this chunk of memory.

In version two though, we allow up to five consumers of this memory (four simultaneous render targets and the depth buffer).  The memory is broken up equally by all consumers, so in the maximum case, each render target and buffer has to fit within 2 MB of EDRAM.  You can imagine if I called 10MB small what I think about 2MB.  I’m sure you could just think “Well sure Miller, that’s fine, but we could just create hundreds of little tiles and make it all fit.”

There are two big issues with this.  First, performance would be horrible.  Each tile that is rendered actually will have your *entire* scene rendered on to it, then the results of the tiles glued together.  In a complex scene this could add up very very quickly.  Second (and more importantly) we only allow a maximum of 15 tiles to be created at one time.  If your render target or depth buffer cannot fit inside 2MB of memory with 15 tiles or less, you will fail.

Knowing that, what size of render targets can you make?  What if you have a 2048×2048 render target (surface format of Color) with no multisampling?  Would that fit if you had four of them at the same time?  A quick and dirty way of figuring it out would be this:

2048 * 2048 = 4MB * 4bytes (color) = 16MB (total amount of memory needed) / 2MB (maximum size) == 8

So, you’d need 8 tiles for this buffer to render correctly, 8 is less than 15 so you’d be safe.  What if you added 2x multisampling though?

2048 * 2048 == 4MB  * 8 bytes (color+ms) == 32 MB (total amount of memory needed) / 2MB (maximum size) == 16

Nope, 16 tiles is too many, this wouldn’t fit.  What if you didn’t have a depth buffer though?  Depth buffer counts as a buffer in the EDRAM so without it, you’d have 2.5MB per surface available:

2048 * 2048 == 4MB  * 8 bytes (color+ms) == 32 MB (total amount of memory needed) / 2.5MB (maximum size) == 13

13 tiles, you’d fit again!

It’s also important to point out that not all tiles are created equal.  Tiles aren’t calculated based on a memory size, but on a pixel size.  Odd shaped (ie, non-square) render targets will create odd shaped tiles, and the last tile may be larger than needed to account for that.  For example, if you have a 1280×720 surface and 3 tiles used in that, you can be assured that you don’t have 3 separate tiles each of size 426.67×720.  Each tile is rounded up to the next size it can be (normally a mutliple of 32).  In the case above, that 1280×720 surface would really be three tiles of size 448×720 with the third title having some “empty” space in it.  So if you do your little math above and it comes to exactly 15 tiles, you still may be too big if the tiles aren’t the size you’d expect.

Do I really expect someone to try to create and use four simultaneous 2048×2048 Color render targets with 4x multisampling and a 32bit depth buffer?  Well no, because as you’ve seen here, it would fail!  However, if it does fail, at least this hopefully explains why!

By the way, in reference to my fake first question.  You can actually do this just fine, so long as you aren’t using 4x multisampling, and even with 4x multisampling, it just barely doesn’t fit with a depth buffer (1900x1080x16bytes == 31.3 MB / 2MB == 15.6 tiles).  Four 2x multisampled render targets at 1080p would fit though.

Why CornflowerBlue?

This post will be purely speculation by me!

Take a time travel machine back in time to early 2003.  It might have even been late 2002, but I think it was 2003. I was coming up with the concepts and code that would eventually be my first kick start book, and was rendering everything on a bland black background.  For some things, black makes sense, but it’s hard to see shaded objects (and particular shadows, etc) on black objects.  Black in general is a horrible color to use as a clear color.  If you clear your scene to black, then render a model and see nothing but black, what went wrong?  Was the model not drawn because your camera is facing the wrong way?  Was the model drawn, but not colored because your pixel shader wasn’t set?  You could tell the difference if your background wasn’t black.

I needed something brighter, and white was out of the question.  I can stare at a white screen all day as I type text, but a white background with a single 3D object on it is just too contrasting and is ugly in my opinion.  So i needed a color that was light, but not too light, dark, but not too dark, and it needed to be something that I would feel comfortable using for just about anything.

So, as I was inside visual studio, I typed “System.Drawing.Color” then hit the extra period and started scrolling through intellisense, stopping at ones that sounded promising and trying them out.  I eventually narrowed it down to a light shade of blue.  I had narrowed my choice down to “LightBlue” “DodgerBlue” “PowderedBlue” “RoyalBlue” and “CornflowerBlue”.  For various reasons I eliminated a couple more and came down to a list of three left.

I had to choose between CornflowerBlue, RoyalBlue, and DodgerBlue.  I tried various models on each of the background colors, and finally decided that RoyalBlue and DodgerBlue were too “bold” and contrasted too much, but CornflowerBlue was a much more “calm” color, and everything I tried looked good against it.  Plus who wants to use a color called “RoyalBlue” or “DodgerBlue” when “CornflowerBlue” is such a cooler name.

If you’ve read my Kickstart book, the vast majority of sample code in there clears all of the backgrounds to CornflowerBlue.  Every sample I’ve written since that point in time does as well.

Can I say with any sense of certainty that everyone else uses it because I did way back then?  Probably not, I’m sure there are people who haven’t even read that book!  At times though, I like to delude myself and think I started the craze way back then. =)

Not quite what I had in mind…

Well, so far my promise to myself to write new blog posts more often has been working out well.  I’ve almost written as much this week as I did the entirety of last year (and I have to admit, four blog posts over the course of a year is pretty pathetic, which is what I had last year).

This post though doesn’t have any interesting anecdotes from our latest release, and in fact isn’t even about XNA Game Studio or game development at all!

As part of my exercise of “writing more” one of the things I had to do was go back and see what I was writing about back in the day when I was enjoying my blog posting, so over the course of today I went back and re-read every post I ever made.  It was an interesting experiment to say the least, I’m surprised at the number of things I read that I just had completely forgotten.

A couple of the posts I found were related to World of Warcraft, which is what this post will be about.  They were about a year apart, and they were each essentially scathing reviews of the state of the game.  While I most likely really did feel so annoyed when I wrote them (and had cancelled my account each time), the fact remains I still play the game to this day.  While many people bemoaned the expansion and how much it “changed the game”, I for one, enjoyed the changes.  There is much less of a brick wall when you hit the level cap than there was before, and there are plenty of things to do regardless of what type of player you are or were.

In my original WoW life, I was a “hardcore raider”.  We raided every day from 6:30 until 11,12, whenever we felt finished for the night.  We cleared Molten Core, Onyxia, Blackwing Lair, ZG, AQ20/40, and Naxxramus (although to be fair, I left the guild after BWL).  My schedule became to the point where I couldn’t meet those demands and amongst other reasons I left that guild.

That began my second WoW life, where I decided to start over on a PvP server.  I won’t get into my philosophies on the pvp servers because I don’t want to be inundated with a series of “l33t speak” that I don’t understand telling me how much I suck.  I maxed out multiple characters on the pvp server, killed thousands upon thousands of my “enemies” (there were no cross server battle grounds back then), and there is absolutely no doubt in my mind that the pvp ruleset isn’t for me.  I am a carebear through and through apparently.

Around the time I was realizing this and getting frustrated though, my original “hardcore” characters had the option to move.  My old server was too big and had queue’s every night, and all characters were invited to move to another new server.  Sensing this was a great time to see if I still enjoyed the game without the pvp annoyance and removing myself from the pressure of raiding constantly, I moved all of my characters to the new server and started playing again.  I joined a little guild, had a bit of fun.. They merged with a huge guild and I considered that a big mistake for a variety of reasons.  Shortly after that merge, I left the big guild, and reformed the old little guild, bringing most of the original members back.

So now I’m the guild leader of some random guild on a brand new server.  We were the definition of casual, and happy that way.  Well, most of us were.  Some were annoyed we weren’t doing the big 40man raids (I’d already seen so much of Molten Core i never wanted to step foot in it again), and they left.  The beta for the expansion was just around the corner though, and that’s where we all started playing more again.  Everyone in the “core” of the guild was in the expansion beta as well.

Once the expansion came out, I decided the name of the old guild was stupid, and we needed to find a much more stupid name to call ourselves, so I kicked everyone out of <Dark Crusade> and created the guild <Less Than Three>.  For those who are “unaware” Less Than Three is <3, which is an emoticon for a heart.  Naturally, our guild tabard is pink with a heart.  That still annoys some people, but eh, I get a kick out of it.  So anyways, the expansion came out, and we were invigorated, so many new quests, so many new dungeons, so much to do!

So we all leveled up with varying levels of speed, and ran all kinds of dungeons along the way.  It was good fun.  Eventually we got to the point where we decided we were ready, we were going to run a “heroic”.  We were going to collect epic loots and slaughter the place.  We decided we would try heroic Slave Pens because at the time you needed revered reputation to run a heroic and that was the easiest faction to get rep with, and on top of that was supposedly one of the easiest heroics in the game.  We gathered at the entrance, we walked in, we were ready to do great things.

We wiped on the first pull.  Twice.  We wiped on the second pull.  We were all red before we got to the first boss.  We did kill that first boss though before we decided we weren’t ready for heroics yet.

Looking back at it now, it’s pretty funny, but at the time, the thoughts were “Holy crap, this is impossible.”  We yawn through most of them nowadays, but I always look back at that first wipe fest with fond memories..

Anyway, finally around November of last year I decided as a guild we needed to start doing more, and that meant Karazhan.  As I stated earlier, we are an extremely small casual guild, but I figured that doesn’t mean we were bad players (half of us came from the hardcore raids back in the day), we were just not focused on being #1 anymore.  When I say small though, I mean not even large enough to run Karazhan (ie, less than 10 players keyed).  We had all the core classes covered though.  We had enough tanks and healers, all we needed was DPS classes.  I figured we could just find random pick up group (PUG) members to fill out our DPS slots, and that’s what we started doing.

We had some success too.  Soon we were killing multiple bosses and things were going well, when we eventually hit a brick wall.  We had gotten to the point where we could take just about any random PUG and clear through Curator.  When I say any random PUG, i mean just that as well.  We’ve had a PUG who did half the damage I did (I’m the main tank).  We’ve had a PUG who went out of his way to break any crowd control that existed.  We’ve had a PUG who decided to use his pet to pull a group of mobs that weren’t even in the same room as us.  Actually, that was all the same guy.  He didn’t understand why I didn’t invite him back next week because of how awesome he was.  Where was I?  Oh yeah, brick wall.  Shade of Aran was our brick wall.

This is what Shade of Aran had taught me.  At the time, the majority of our raids were made up with 8-9 guild members and 1-2 PUGs.  I learned that we could 8 man every boss up until Curator, and that we could 9man Curator.  I also learned that a random pug in all greens who doesn’t understand the need to stand still during Flame Wreath is a recipe for disaster.  Unlike any boss before it, Aran punishes players for doing things wrong, and if there is one thing you can count on a pug doing, it’s “something wrong”.

So, I started trying to recruit players to help us out.  I talked to all of the PUG members we had with us that went well, but most of them were in established guilds and were with us on an alt for easy/free badges and loot.  The ones interested in joining were the ones who were horrible.  This is where I learned that I am a horrible recruiter.  I simply cannot do it at all!

Which brings us to this extremely long winded post!  Consider this my last lame attempt at recruitement.  Our raid times are pretty inflexible (given our small size and the schedule requirements of some of our members), but our normal raid nights are Friday and Saturday nights, from 8pm to Midnight pacific time.  We have killed all of the bosses in Karazhan with the exception of Prince, Nightbane and Netherspite (see my note on pugs above), but hope to have those done soon.

So, if you’re interested in raiding Karazhan (and eventually Zul’Aman soon) on those days, and random other dungeons throughout the week (all in the evenings, we’re all at work during the day you know), you should contact me!  If you’re a warlock, even better, since all our current warlocks are alts of characters already in Kara and some bosses (I’m looking at you Illhoof) could really use a warlock.  I really don’t care what class you are though.  Do you want to tank?  Awesome, that means I could bring an alt sometimes.  Want to heal?  I’m sure our healers would like to bring an alt sometimes too!  Got DPS, that’s awesome, we always need DPS.

Now, we’re a pretty accomodating guild for the most part.  I’m entirely too helpful for my own good most times.  Given the extremely public nature of this post though, I’m going to have to be a little more particular on the things I am looking for.  I understand the concept that beggars can’t be choosers, but I don’t feel like being taken advantage of and helping someone get ready for raids with us just to have them disappear.  If you want to create a new character on the server, we’ll help you level up when it’s convenient for us, but it won’t be all that often.  I’d much rather if you were already level 70 and keyed.  If you want to tank in Kara, you’ll need to be uncrittable, and have a minimum of 12k hps and 12k armor (20k if druid).  If you want to heal, you’ll need at least 1000 +heal, and preferably more, along with a decent mana regen and mana pool.  If you want to DPS, I hope you can sustain 400+ the entire run.

To be honest, I hate putting any kind of preconditions on it at all.  However, i think what i have is pretty reasonable.  I don’t care what class you are, what spec you are, so long as you are a good player, you’d be welcome.  So after all that, if you’re still interested, you should contact me, either here on these boards, or in game.  We play on the Eitrigg server as Alliance, and you can contact any character that starts with “Miller” in the guild <Less Than Three>.

We have a web site as well at http://lt3.darkcrusade.org (as you can see our old guild name remnants still exist), but it’s been flaky the last few days to say the least.  Hopefully it is resolved soon.

P.S. How sad is it that I’m posting a recruiting post on my blog?  I almost feel dirty.

Why purple?

One of the things I’m going to try to do this year is write more on my blog.  The publisher for my books is hoping I’ll write something new for them this year as well, although at the moment I don’t know if I’d have the time, or what I’d write about anyway..  Anyone have suggestions on topics they’d like me to cover in a book or a blog post?  Shawn normally goes a great job staying ahead of the curve so the possibilties of topics diminishes some. =)

So for now I’m just going to post a random anecdote that was asked in our internal alias one day..  Why does the framework clear the targets (render targets, back buffer) to purple when RenderTargetUsage.DiscardContents is turned on?

When I originally implemented that feature, I wanted something that jumped out at me and was extremely noticeable.  I picked the brightest, most obnoxious shade of neon green I could.  It did the trick, it was instantly noticeable when it was there.  As time went on though, I kept seeing it all the time, day in, day out, over and over again.  It irritated me something fierce and eventually I decided I just had to change it to something much less obnoxious, so I picked a dark purple.  The intention was to switch it back to the bright neon green before we shipped to ensure everyone got to experience the joy that was that color.

As time went on though, we all got used to the purple.  It was pretty quickly and easily recognized and that was the goal for the clear to begin with.  Why torture everyone’s eyes and have them all hate me when everyone is soothed by the purple?

So, why purple?  To avoid the hate mail that would have come from the original neon green!

Big Announcements!

Well, another conference has come and we have more announcements it seems.  Hard to believe I’ve neglected this blog for so long that it’s been since last August that I wrote anything.  This is probably because we have so many other team members who are doing such a great job with their own blogs, mine almost seems redundant!

Nevertheless, some great things annouced today that are quite exciting.  You can read all about them on the XNA Team Blog as well.

The first big announcement was Xbox LIVE community games coming this holiday season (with a special preview for a limited time right now).  Later this year you will be able to develop your own games using the XNA Creators Club subscription and upload your game to Xbox LIVE for the whole world to see and play for free (assuming it passes a peer review).  What’s more, if you believe your game is a money maker, you will actually be able to sell your game and make money.  Exciting times are coming indeed.

As part of this, there are seven community games available fore a very limited time right now.  If you want to try them out (and I heartily recommend you do), first go to the market place on your Xbox and go to the Game Store and navigate down to XNA Creators Club and download the new Game Launcher.  Once it’s downloaded, navigate back to the Games Library on the games tab, and under “My Games” navigate over to the “XNA Creators Club” twist and press Y to see the list of games to download.  They’ll appear under that twist to play once they’re downloaded as well.

While this was a huge announcement in and of itself, we actually made a second announcement today as well.  Starting with XNA Game Studio 3.0 you will not only be able to create games for Xbox and Windows, but you’ll also be able to create them for your Zune as well.  You’ll even be able to use the wireless capability of the Zune to play against other nearby Zune’s in multiplayer games!

As I’ve sometimes implied with my reflection posts and the like, annoucements like we made today are the reason I do what I do.  It’s been my stated goal for years now to bring managed code and gaming to the masses and we’re getting there, one game at a time.