Hannawell

I want to disable backbuffer clear. Though I have removed the Clear from my draw func
it still gets cleared to black on Xbox360. Run the same thing on PC and the mystery
clear doesn't happen (stuff I'm drawing correctly smears across the screen).

I also tried to workaround w/ ResolveBackBuffer to a texture and draw this
back at the beginning of each frame but thats not working for me either.
In this case my Draw() looks like:

Draw Backing Texture using Quad
Draw new items
ResolveBackBuffer -> Backing Texture

I even tried double buffering the backing texture w/ no luck.

Thirdly, I tried RenderTargets, but they also seemed to be getting cleared each frame
as well! I would think there's gotta be a way for rendertarget contents to persist
for use in the next frame


Re: XNA Framework persistent backbuffer OR renderTarget (on 360) possible?

Shawn Hargreaves - MSFT

On Xbox all rendertargets and the backbuffer share the same memory, because there is only a single special place where the GPU sends all the output from rendering.

This means that whenever you change rendertarget (either to a custom target, or switching back to the backbuffer, or when the Present happens at the end of a frame) the previous contents of all rendertargets are lost forever.

If you want to preserve the data, you can Resolve it (either via ResolveBackbuffer or ResolveRenderTarget, depending on which you are using). You have to do the resolve before you switch target, though, or the data will already have been lost!





Re: XNA Framework persistent backbuffer OR renderTarget (on 360) possible?

Hannawell

Thanks, that sheds some light on my problem, but I haven't solved it yet.

As I mentioned, I had tried using ResolveBackBuffer. However, I think there may be a problem with it when used for per-frame persistent feedback. It does seems to work ok for non-feedback captures.

Its strange, but w/ feedback (resolve tx -> background image) I think I'm seeing is a lack of pixel accuracy when the resolve copies to the texture (maybe a shifting of image by a single pixel each frame). Running full 60fps this is hard to decipher. When I tied the resolve to a button trigger (slowing feedback down), I see both a vertical and horizontal shift after each resolve-feedback cycle.

Note, I am never switching rendertargets, always drawing to BackBuffer.






Re: XNA Framework persistent backbuffer OR renderTarget (on 360) possible?

Hannawell

Looking at further, its probably just a uv shift I need to counteract. I'm not using a sprite,
so I have control of the uvs on my quad (currently 0,0 -> 1,1) using a 4 vert trifan. Whats strange is the shift is in v-direction on one of the quad's triangle and u-direction on the other. Since the 2 tris share uv's I can only guess some kind of sampling problem, though I'm using "point".

Thinking I should be able to resolve w/ enough fiddling.




Re: XNA Framework persistent backbuffer OR renderTarget (on 360) possible?

Shawn Hargreaves - MSFT

In D3D, texture coordinates refer to the top left of each texel, so to make that line up exactly with screen pixels for drawing a full screen quad, you need to subtract 0.5 of a pixel from your position coordinates.

The XNA SpriteBatch class will do that for you, but if you're using your own drawing code, it's up to you to apply the appropriate half pixel offset to keep everything lining up properly.





Re: XNA Framework persistent backbuffer OR renderTarget (on 360) possible?

Hannawell

Thanks for that last info! The shifting feedback wierdness is resolved after translating my quad by half a pixel.

One more issue to resolve. The backbuffer feedback seems to work only if I occasionally trigger the ResolveBackBuffer (i.e. on a button press). If I invoke the ResolveBackBuffer at the end of EVERY draw, nothing at all draws. This is regardless of whether I try to draw any items with the backing texture. This might be easy to reproduce in any demo.

When I trigger the ResolveBackBufffer grab on button press, I do see a black flash. Is it possible the display buffer transfer (of the backbuffer) could be failing on the frame the resolve occurs in

Anyone seeing the momentary flash I'm describing when they use the "ScreenGrab" code thats floating around




Re: XNA Framework persistent backbuffer OR renderTarget (on 360) possible?

Shawn Hargreaves - MSFT

This would be a good time to dig out PIX for Windows (part of the DirectX SDK). It can capture a ton of detail about all the rendering that happens in a frame, so you can dig through it and try to see what's going wrong.

If you switch to the debug D3D runtime (also part of the DX SDK) you can use a tool like dbmon to capture more detailed logging output about any D3D failures, too.





Re: XNA Framework persistent backbuffer OR renderTarget (on 360) possible?

Hannawell

Note, the display problem I describe with calling ResolveBackBuffer on every draw do not
happen when running windows version of XNA, only on the Xbox 360.

Are you saying PIX can be used to resolve xbox 360 platform specific XNA issues





Re: XNA Framework persistent backbuffer OR renderTarget (on 360) possible?

Hannawell

Need to clarify/correct when I said "nothing draws"... I should have said "nothing displays".
During the display "blackout", the backbuffer is correctly drawn to even feedbacks on itself
properly. I determined this after putting the continuous grab (on/off) on a button toggle.




Re: XNA Framework persistent backbuffer OR renderTarget (on 360) possible?

Shawn Hargreaves - MSFT

PIX only works on Windows.

Strange problem, I don't have any clue what could be causing this!





Re: XNA Framework persistent backbuffer OR renderTarget (on 360) possible?

Hannawell

I verified the problem is easily reproduced using the 2D sprite demo from the article,
"Your First Game: Microsoft XNA Game Studio Express in 2D". Just modify
w/ this:

public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
ContentManager content;
Texture2D rtt;
...
protected override void LoadGraphicsContent(bool loadAllContent)
{
if (loadAllContent)
{
myTexture = content.Load<Texture2D>("mytexture");
spriteBatch = new SpriteBatch(graphics.GraphicsDevice);

PresentationParameters pp =
graphics.GraphicsDevice.PresentationParameters;

int w = pp.BackBufferWidth;
int h = pp.BackBufferHeight;
rtt = new Texture2D(graphics.GraphicsDevice, w, h, 1,
ResourceUsage.ResolveTarget, SurfaceFormat.Color,

ResourceManagementMode.Manual);
}
}
...
protected override void Draw(GameTime gameTime)
{
graphics.GraphicsDevice.Clear(Color.CornflowerBlue);

//draw our sprite

spriteBatch.Begin(SpriteBlendMode.AlphaBlend);
spriteBatch.Draw(myTexture, spritePosition, Color.White);
spriteBatch.End();

base.Draw(gameTime);

graphics.GraphicsDevice.ResolveBackBuffer(rtt);
}
}





Re: XNA Framework persistent backbuffer OR renderTarget (on 360) possible?

Shawn Hargreaves - MSFT

Interesting... could you file a bug on this over on the connect site please, and include that repro code example

Thanks for the report!





Re: XNA Framework persistent backbuffer OR renderTarget (on 360) possible?

Tom Miller - MS

ResolveBackBuffer (particularly on Xbox) is destructive. The behavior you are seeing is what I would expect, since you've resolved the back buffer, drawn nothing else, and then presented it to the screen. It should present the back buffer (which is now nothing), which is what it is doing.

You will need to actually do something with 'rtt' in your example (ie, drawing it back to the screen after some post-processing) in order to actually have somethign be shown.

While we are trying to come up with more consistent behavior between the two platforms, for now it's best to assume that either of the two "Resolve" operations (ResolveRenderTarget/ResolveBackBuffer) will destroy the contents of that data after the operation is complete (the render target will be 'empty' and the back buffer will be 'empty' after each operation). Making this assumption in your code and handling it that way (ie, multiple passes or what have you) will help make the code much more platform agnostic..






Re: XNA Framework persistent backbuffer OR renderTarget (on 360) possible?

Hannawell

> You will need to actually do something with 'rtt' in your example

If you read further back in this thread, this is my primary intent, and I have done it in my application. It exhibits the same display 'quits' behavior. Even when I draw with the backing texture, the display disappears on frames where the resolveBackBuffer is performed.

Since I was seeing the behavior either way, I figured I'd just post the simpler case.

Based on what I've seen I'm 99.99% sure that if I add a sprite draw using the rtt to the sample code above that the display behavior will not change. I'll report back as soon as I've done that.

> ResolveBackBuffer (particularly on Xbox) is destructive.

So how is drawing the rtt into it beforehand going to prevent this destruction
Assuming the Present happens in the EndDraw() it still will have an empty backbuffer, no
In my mind, drawing w/ the rtt should have no more impact on whether the backbuffer is displayed than doing the clear or drawing the sprite.

Would it be legal/possible to postpone the Resolve until after the Present()




Re: XNA Framework persistent backbuffer OR renderTarget (on 360) possible?

Hannawell

I verified that drawing the rtt in the sample code had no positive effect. The Draw() was modified as:

protected override void Draw(GameTime gameTime)
{
graphics.GraphicsDevice.Clear(Color.CornflowerBlue);

// draw previous backbuffer on stationary sprite
spriteBatch.Begin(SpriteBlendMode.None);
spriteBatch.Draw(rtt, Vector2.Zero, Color.White);
spriteBatch.End();

//draw our animated sprite
spriteBatch.Begin(SpriteBlendMode.AlphaBlend);
spriteBatch.Draw(myTexture, spritePosition, Color.White);
spriteBatch.End();

base.Draw(gameTime);

graphics.GraphicsDevice.ResolveBackBuffer(rtt);
}