2015-06-14 27 views
0

問題是更多的C#相關,但我最近開始學習sharpdx,並提出了兩種初始化資源的方法。首先將資源(本例中爲Texture2D)存儲爲全局變量。然後,在代碼分配值給它,並將其傳遞到sharpdx的方法(和向下C++該sharpdx封裝)'在C#中使用範圍'和sharpdx

backBufferPtr = m_swapChain.GetBackBuffer<Texture2D>(0) 
_renderTargetView = new RenderTargetView(m_device, backBufferPtr); 

然後呼叫處理就可以了,在調用它的類的處置方法中,基本上保持該Texture2D整個生命週期的類。

的其他用途使用的語句:

using(Texture2D backBuffer = _swapChain.GetBackBuffer<Texture2D>(0)) 
{ 
    _renderTargetView = new RenderTargetView(_d3d11Device, backBuffer); 
} 

而且我不知道爲什麼第2個實際工作。我在調試器中進行了檢查,只要我停止使用語句

backBuffer.NativePointer 
_renderTargetView.Resource.NativePointer 

指向存儲器中的同一個對象。只要我離開使用語句backBuffer被放置並且不再指向任何東西,但_renderTargetView.Resource不會改變,並且仍然指向它在using語句中所做的對象。只要我離開using塊

class innerClass 
{ 
    public Texture2D someResource; 
} 
/****/ 
innerClass ic = new innerClass(); 

using (Texture2D t2 = m_swapChain.GetBackBuffer<Texture2D>(0)) 
{ 
    ic.someResource = t2; 
} 

這裏T2和ic.someResource得到安置,並點什麼,這是我沒有料到它的工作中:

我做了一個快速測試第一個地方。現在

的問題是:

1)我應該假定,在第一個例子,它實際上是sharpdx的方法,該方法可以確保內部resuorce沒有得到處置,即使C#對象,進行了傳遞給它,是嗎?如果C#決定覆蓋該內存塊,它會不會在某個時候崩潰?

2)傳遞這些資源的更好/更安全的方式是什麼?使用block,還是在開始時聲明並在最後處理?

+0

我曾經在SlimDX上工作過,在那裏我看到了一個非常類似的現象。我注意到SlimDX管理其內部參考計數器。當你調用GetBackBuffer時,它會增加ref計數器,當你處理它時 - 它只是減少參考計數器,這可能會導致只有當計數器爲零時纔會實際清理紋理。在BackBuffer示例中,引用仍然由系統保留,因此未被清除,在第二個示例中,最後一個引用被處理。我會檢查SharpDX上的行爲是否相同。 – MaMazav

回答

0

SharpDX保留對底層圖形資源引用的計數。因此,例如,當你獲得到後臺緩衝區的引用:

Texture2D backBuffer = _swapChain.GetBackBuffer<Texture2D>(0)

然後獲取一個渲染相同的底層資源的目標視圖:

_renderTargetView = new RenderTargetView(_d3d11Device, backBuffer);

您需要處置他們兩個以及交換鏈從GPU釋放後臺緩衝區資源。


什麼是傳遞這種資源的更好/更安全的方法?使用block,還是在開始時聲明並在最後處理?

雖然依賴於使用情況,但從我所看到的情況來看,通常獲取資源句柄的類將在它自己的實現IDisposable中處理它。

+0

Ach,這很有道理,謝謝你的洞察力:) – DemoBytom