具有重複對應之並排存取限制
具有重複對應的並排存取存在著諸多限制,例如複製具有重複來源和目的地的串流資源時,或是轉譯至在轉譯區域中共用的並排時。
複製來源和目的地重疊的串流資源
如果 Copy* 作業的來源和目的地區域在複製區域中有重複的對應,造成即便兩個資源都非串流資源,也會發生重複,而 Copy* 作業支援重疊複製,則 Copy* 作業將正常運作 (如同資源先複製至暫存地點,再複製至目的地)。 不過,如果重疊並不明顯 (例如來源和目的地資源不同卻共用對應,或對應在指定的表面上重複),則共用並排上的複製作業結果就會是未定義。
複製至目的地區域具有重複並排的串流資源
如果目的地區域有重複的並排,除非資料本身完全相同,否則,將其複製至串流資源,將於這些並排中產生未定義的結果;不同的並排可能會以不同的順序寫入並排。
重複並排對應的 UAV 存取
假設串流資源上的未排序存取檢視 (UAV) 在其區域中有重複的並排對應,或與繫結至管線的其他資源有重複的並排對應。 如同 UAV 的記憶體存取通常沒有順序一樣,如果由不同的執行緒執行作業,則這些重複並排的存取順序就不會定義。
在變更並排對應或從外部對應更新內容後進行轉譯
如果串流資源的並排對應發生變更,或對應的並排集區並排透過其他串流資源的對應進行內容變更,而串流資源將透過轉譯目標檢視或深度樣板檢視轉譯,則應用程式必須清除 (使用固定函式 Clear API),或使用 Copy*/Update* API 複製要轉譯區域中的已變更並排 (無論對應與否)。
如果應用程式沒有在這些案例中進行清除或複製作業,則指定轉譯目標檢視或深度樣板檢式的硬體最佳化結構就會過時,並導致部分硬體上發生轉譯結果回收,並在不同硬體之間造成不一致。 這些由硬體使用的隱藏最佳化資料結構可能會位於個別對應的本機上,而相同記憶體的其他對應無法加以檢視。
清除資源檢視 (將資源檢視中的所有項目設為單一值) 時,您可以使用矩形來清除轉譯目標檢視。 針對支援串流資源的硬體,清除資源檢視時,也需支援使用矩形清除僅具深度之表面 (沒有樣板) 的深度樣板檢視。 這項作業可讓應用程式僅清除表面上的所需區域。
如果應用程式需要保留對應發生變更之串流資源中的現有記憶體內容,該記憶體必須符合清除需求。 應用程式可以先儲存並排對應發生變更的內容 (將其複製到暫存表面)、發出必要的清除命令,然後將內容複製回去,以做為因應。 雖然這會完成為累加式轉譯保留表面內容的工作,其缺點在於,由於此舉可能會喪失轉譯最佳化,表面上的後續轉譯效能有機會受到影響。
如果並排同時對應至多個串流資源,且並排內容會由任一串流資源透過任何方式操控 (轉譯和複製等),如果相同的並排將透過其他任何串流資源轉譯,則如同先前所述,該並排必須先進行清除。
轉譯至位於轉譯區域外部的並排
假設串流資源中的區域會進行轉譯,而轉譯區域參照的並排集區並排也會從轉譯區域外部進行對應 (包括透過其他串流資源,無論是否同時)。 即使基礎記憶體配置相容,透過其他對應檢視時,也不保證轉譯至這些並排的資料能正確顯示。 原因在於,部分硬體使用的最佳化資料結構,可能位於可轉譯表面之個別對應的本機上,且無法供相同記憶體位置的其他對應檢視。
只要將轉譯的對應複製至位於相同記憶體且可能進行存取的其他所有對應 (或者,如果舊有內容已不再需要,也可清除該記憶體,或將其他資料複製至該處),就能加以因應。 這個因應措施雖然看似多餘,卻能讓相同記憶體中的其他所有對應正確了解如何存取其內容,而且至少能保有以單一實體記憶體備份節省記憶體的效果。
此外,來回切換共用對應的不同串流資源 (除非只進行讀取) 時,您必須在參數間的多個並排資源之間,指定資料存取順序限制 (屏障)。
轉譯至位於轉譯區域內部的並排
如果串流資源區域轉譯至其中的轉譯區域,會有多個並排對應至相同的並排集區位置,這些並排的轉譯結果就會是未定義。
串流資源共用並排之間的資料相容性
假設多個串流資源會對應至相同的並排集區位置,而每個資源都會用來存取相同的資料。 只有在已執行有助於避免發生硬體最佳化結構問題的其他相關規則、指定適當的屏障 (在多個並排資源之間指定資料存取順序限制),而且串流資源皆彼此相容,這個情境才會視為有效。
此處將描述上述最後一個條件,以說明串流資源共用並排不相容所代表的意義。 造成跨越重複並排對應存取相同資料無法相容的條件,包含使用不同的表面維度或格式,或是存在於表面上的轉譯目標或深度樣板繫結旗標有所差異。 如果您後續透過來自不相容資源的對應來進行讀取或轉譯,使用一種對應類型來寫入記憶體將產生未定義結果。
如果先使用新的資料來初始化其他資源共享對應 (回收記憶體以做為不同用途),由於資料並不會在不相容的解譯之間滲出,後續的讀取或轉譯作業將可順利運作。 不過,像這樣切換存取不相容的對應時,您必須指定屏障 (指定多個並排資源之間的資料存取順序限制)。
如果任何資源共享對應之間並未設定轉譯目標或深度樣板繫結旗標,就會大幅減少限制。 只要格式和表面類型 (例如 Texture2D) 相同,就能共用並排。 不同格式可相容的案例,會包括 BC* 表面和每一元件格式相同大小的未壓縮 32 位元或 16 位元,例如 BC6H 和 R32G32B32A32。 許多每一項目格式 32 位元也可具有 R32_* 的別名 (R10G10B10A2_*、R8G8B8A8_*、B8G8R8A8_*、B8G8R8X8_*、R16G16_*);非串流資源一律會允許這項作業。
如果格式相容,且並排填滿純色,就允許在封裝和非封裝並排之間共用。
最後,如果資源共用並排對應除了全數沒有轉譯目標或深度樣板繫結標籤之外,毫無任何共通點,則只有填入 0 的記憶體會安全地進行共用;針對指定資源格式的定義,對應將使用 0 的解碼結果顯示 (通常只有 0)。
相關主題