SlimDX9 - 使用RenderToSurface的Device.Reset

时间:2013-01-03 15:54:22

标签: c# reset slimdx

我有一个具体的问题。

我一直在尝试在窗口调整大小后重置SlimDX9设备以更改分辨率。一切都在Pool.Managed,没有字体,没有Stateblocks,一切都工作但纹理+表面+ RenderToSurface组合。我需要将纹理作为着色器的renderTarget,以便稍后进行后处理,因此我需要将其调整为clientize以及backbuffer。

我确实创建了这样的组合:

rtTexture = new Texture(this.Device, this.owner.ClientSize.Width, this.owner.ClientSize.Height, 1, Usage.RenderTarget, Format.A8R8G8B8, Pool.Default);
rtSurface = rtTexture.GetSurfaceLevel(0);
rtHelper = new RenderToSurface(this.Device, this.owner.ClientSize.Width, this.owner.ClientSize.Height, Format.A8R8G8B8, Format.D24S8);

调整窗口大小时,我会

rtTexture.Dispose();
rtSurface.Dispose();

我已尝试过两次

rtHelper.OnLostDevice();

rtHelper.Dispose();

当然,在Device.Reset(getParameters())之后我重新创建资源/调用rtHelper.OnResetDevice(),两者都不起作用。我尝试了Dispose()和OnDeviceLost()的每一种组合。

在失败的重置和通常的InvalidCall之后,我收到了这条消息

All user created D3DPOOL_DEFAULT surfaces must be freed before ResetEx can succeed. ResetEx Fails.

所以我对应用程序进行了PIX,并发现纹理和表面都没有处理(在被破坏的列中有“never”)DESPITE事实上,.Dispose()在这两个对象和IsDisposed上被显式调用在Device.Reset()之前是真的。

删除组合会使重置正常。问题出现在RenderToSurface重置和/或纹理+表面。

我像这样使用RenderToSurface:

rtHelper.BeginScene(rtSurface, new Viewport(0, 0, this.owner.ClientSize.Width, this.owner.ClientSize.Height));
{
    Device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, FogColor, 1, 0);
    terrainEffect.BeginPass(0);
    RenderTiles();
    terrainEffect.EndPass();
}
rtHelper.EndScene(Filter.None);

甚至可能吗?这是SlimDX中的错误吗?我能做什么? 我可以以某种方式访问​​非托管资源,并手动销毁它们吗?

请帮助,我不知道接下来该做什么。我非常感谢对此的任何回应。感谢。

编辑:我试图绕过RenderToSurface并使用Device.get / setRenderTarget()并且问题仍然存在,表面和纹理不会被Dispose()破坏之前Device.Reset()。

1 个答案:

答案 0 :(得分:1)

我已经明白了! 对于遇到相同问题的任何人:

如果您正在使用在一个着色器传递中创建的纹理,将其指定给着色器并在第二次传递中使用它,请务必在使用之后(Device.Present()之前)设置纹理{{1} }。像这样:

null

其中terrainEffect.SetTexture(hRTTexture, null); 是纹理的处理程序。看起来着色器会锁定纹理,如果着色器上有这样的锁定,SlimDX就无法处理这样的纹理(和相关的表面)。

希望这有助于某人。