如果我打電話給glDrawElements
,其中抽取目標是後臺緩衝區,然後我打電話給glReadPixels
,是否保證我會讀取提取的內容?glDrawElements是否在後臺緩衝區同步?
換句話說,是glDrawElements
阻止呼叫?
注:我觀察這裏的奇怪的問題可以通過glDrawElements
沒有被阻塞引起...
如果我打電話給glDrawElements
,其中抽取目標是後臺緩衝區,然後我打電話給glReadPixels
,是否保證我會讀取提取的內容?glDrawElements是否在後臺緩衝區同步?
換句話說,是glDrawElements
阻止呼叫?
注:我觀察這裏的奇怪的問題可以通過glDrawElements
沒有被阻塞引起...
換句話說,是glDrawElements阻塞調用?
這不是OpenGL的工作方式。
OpenGL memory model構建於「彷彿」規則上。除了某些例外,everything in OpenGL will function as if all of the commands you issued have already completed。實際上,一切都會像每個命令都被阻塞直到完成一樣。
但是,這並不意味着OpenGL實現實際上以這種方式工作。它只需要盡一切努力使出現即可。
因此,glDrawElements
一般不是阻塞呼叫;然而,glReadPixels
(當讀到客戶端內存時)是阻塞呼叫。因爲當返回glReadPixels
時,像素直接傳輸到客戶端內存的結果必須可用,所以實現必須檢查是否有任何正在讀取的幀緩衝區的渲染命令。如果有,那麼它必須阻止,直到這些渲染命令完成。然後它可以執行讀取並將數據存儲在客戶端內存中。
如果您是reading to a buffer object,則不需要glReadPixels
來阻止。由於您正在讀入緩衝區對象,所以客戶端無法訪問的內存將被該函數修改。所以驅動程序可以異步發佈回讀。但是,如果您發出一些取決於此緩衝區內容的命令(如將其映射爲讀取或使用glGetBufferSubData
),則OpenGL實現必須停止,直到讀取操作完成。
簡而言之,OpenGL試圖儘可能延遲阻塞。除非絕對必要,否則你的工作,以確保性能,是幫助 OpenGL這樣做,而不是forcing an implicit synchronization。 Sync objects可以幫助這一點。