我有一个具体的问题。
我一直在尝试在窗口调整大小后重置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()。
答案 0 :(得分:1)
我已经明白了! 对于遇到相同问题的任何人:
如果您正在使用在一个着色器传递中创建的纹理,将其指定给着色器并在第二次传递中使用它,请务必在使用之后(Device.Present()
之前)设置纹理{{1} }。像这样:
null
其中terrainEffect.SetTexture(hRTTexture, null);
是纹理的处理程序。看起来着色器会锁定纹理,如果着色器上有这样的锁定,SlimDX就无法处理这样的纹理(和相关的表面)。
希望这有助于某人。