2015-09-02 24 views
2

要在OpenGL中使用無圖像圖像,您需要使用glGetImageHandleARB創建一個GLuint64手柄。然後,您可以將此句柄設置爲一個統一的image2D變量,並使用該圖像,就好像您以舊方式綁定它一樣。沒有問題。使用紋理/採樣器,還可以將(紋理)句柄設置爲不是採樣器2D,而是設置爲簡單統一的uint64_t變量。這個句柄可以用來在運行時用構造函數sampler2D(句柄)「構造」一個​​採樣器對象。從uint64_t圖像手柄創建image2D

The extension description says:

取樣是使用64位整數表示的手柄,並且可以是 轉換爲和從使用構造64位整數。

圖像使用的是64位整數表示的手柄,並且可以是 轉換爲和從使用構造64位整數。

所以我會假設圖像的構造與採樣器的工作方式相同,但事實並非如此。示例代碼:

#version 450 
#extension GL_ARB_bindless_texture : enable 
#extension GL_NV_gpu_shader5 : enable 

layout(bindless_image, rgba8) uniform image2D myBindlessImage; 

uniform uint64_t textureHandle; 
uniform uint64_t imageHandle; 

void main() 
{ 
    sampler2D mySampler = sampler2D(textureHandle); // works like a charm 
    ... = texture(mySampler, texCoord); 

    ... = imageLoad(myBindlessImage, texCoordI); // works like a charm 

    layout(rgba8) image2D myImage = image2D(imageHandle); // error C7011: implicit cast from "uint64_t" to "int" 
    ... = imageLoad(myImage, texCoordI); 
} 

顯然,無論是image2D(uint64_t中)構造也不在擴展描述中提到的image2D(uvec2)構造是已知的編譯器。我是否錯過了一些東西,或者現在還沒有實現,儘管它應該是?我現在使用的視頻驅動程序是Nvidia的355.82。如果有人能夠說明這是否適用於任何其他驅動程序/供應商的卡,我會很高興。順便說一句,爲什麼我需要這個功能:與紋理句柄相反,圖像句柄不能識別整個基礎數據,而只能識別一個紋理等級。如果您想在着色器中執行任何mipmap或其他分層工作並需要綁定幾個/所有紋理級別,則可以在緩衝區中提供所有級別的句柄,然後根據需要在着色器運行時構建它們。現在,您必須爲您的n個紋理等級定義n個不同的統一的image2D,這非常乏味,特別是在圖像大小發生變化時。

附錄:重現編譯錯誤的最快方法是將image2D(0lu);您的着色器代碼中的某處。

+0

圖像可以被計算着色器寫入,而紋理是隻讀的。 – datenwolf

+0

擴展規範沒有提到您正在使用的任何'samperType(uint64_t)'或'imageType(uint64_t)'構造函數。該擴展提供的構造函數如下:'任何圖像類型(uvec2)//將一對32位無符號整數轉換爲圖像類型'。它從來沒有提到'uint64_t',它不是一種GLSL核心,也沒有一個定義在這個擴展中。 – derhass

+1

你說得對,uint64_t在供應商特定的擴展GL_NV_gpu_shader5中定義。但是,這不會改變問題。即使寫image2D(uvec2(0));產生「從uint64_t」到「int」的隱式轉換。 – mOfl

回答

1

您使用的語法錯誤。將uint64_t投射到圖像的正確語法是:

layout(rgba8) image2D myImage = layout(rgba8) image2D(imageHandle); 

需要多次指定格式。我不知道爲什麼,甚至爲什麼甚至不需要指定格式。這個規範非常模糊。

+0

這確實解決了這個問題。非常感謝你!太糟糕了,編譯器無法提供有用的錯誤消息。 – mOfl