簡體   English   中英

使用clCreateFromGLTexture的opencl / opengl互操作無法繪制到紋理(紋理黑色)

[英]opencl/opengl interop using clCreateFromGLTexture fails to draw to texture (texture black)

設置有些復雜,所以我會盡力詳細說明。

首先,我嘗試使用openCL / openGL互操作。 該代碼在不使用interop cl :: ImageGL時有效,因此基本知識就在那里。 該項目使用了3個主要的openGL上下文(花了很多時間在其中打開openCL上下文)。 我在上下文中使用QGLWidgets。 首先創建一個隱藏的QGLWidget,其他兩個共享隱藏的上下文。 2個QGLWidgets中的每一個都在各自的線程中運行。 隱藏的QGLWidget將傳輸到創建openCL上下文的線程。

QGLFormat qglFormat;
qglFormat.setVersion(3, 3); 
qglFormat.setProfile(QGLFormat::CoreProfile);

m_hiddenGl=new GLHiddenWidget(qglFormat);
m_hiddenGl->setVisible(false);

m_view1=new GLWidget(qglFormat, m_hiddenGl);
m_view2=new GLWidget(qglFormat, m_hiddenGl);
 ...
 QThread *processThread=m_process.qThread();

m_hiddenGl->doneCurrent();
m_hiddenGl->context()->moveToThread(processThread);

GLWidget是一個自定義類,它啟動其自己的線程並移動上下文,GLHiddenWidget再次是自定義類,但基本上只是重寫了所有使makeCurrent避免被主線程調用的函數。

在啟動過程線程內部如下

m_hiddenGl->makeCurrent();
hdc=wglGetCurrentDC();
glHandle=wglGetCurrentContext();

cl_context_properties clContextProps[]={ 
    CL_CONTEXT_PLATFORM, (cl_context_properties)m_openCLPlatform(),
    CL_WGL_HDC_KHR, (intptr_t) hdc,
    CL_GL_CONTEXT_KHR, (intptr_t) glHandle, 0
};

m_openCLContext=cl::Context(m_openCLDevice, clContextProps, NULL, NULL, &error);

這都是一個去。 從這一點出發,幾個內核依次對輸入數據(即圖像)執行。 所有內核都成功(沒有錯誤),但是使用openGL紋理寫入數據的一個內核無法寫入任何內容。 當使用openCL cl :: Image2d時,即使將openCL上下文創建為互操作,它也可以正常工作(產生正確的輸出)。

在創建所有openGL上下文之后和openCL上下文創建之后(也在與openCL上下文相同的線程中),將創建openGL紋理。 在processThread的開始,紋理由隱藏的QGLWidget和glGenTextures生成。 然后,所有內核與其他openCL緩沖區和映像一起創建。 在內核執行之前,需要完成以下操作。

if(initBuffer) //runs only if buffer size is changed, allways runs first time
{
    m_hiddenGl->makeCurrent();

    glBindTexture(GL_TEXTURE_2D, m_texture);

    //I have attempted to put data in, result is always black from kernel
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glBindTexture(GL_TEXTURE_2D, 0);

    glFinish();

    //m_flags is CL_MEM_READ_WRITE
    m_imageGL=cl::ImageGL(m_openCLContext, m_flags, GL_TEXTURE_2D, 0, m_texture, &error);
}

和簡化的內核。

__kernel void kernel1(__read_only image2d_t src1, __read_only image2d_t src2, __write_only image2d_t dst)
{
    int2 coord=(int2)(get_global_id(0), get_global_id(1));
    uint4 value=255;

    write_imageui(dst, coord, convert_uint4(value));
}

即使我不顯示紋理,圖像仍然是黑色的。 使用cl :: Image2d或cl :: ImageGL時,將從openCL讀取圖像並將其保存到硬盤。 對於cl :: Image2d,對於cl :: ImageGL是正確的,它是黑色的。

我遇到了同樣的問題,並使用了write_imagef() (不要忘記將RGBA值除以255.0 !),而不是在OpenCL內核中解決了write_imageui() ,而沒有更改OpenGL紋理的像素格式(您可以沒有機會這樣做,特別是如果它是現有的紋理,是在大型應用程序的其他位置創建的)。

您必須發布更多代碼給我們,以查找錯誤。

無論如何,我已經編寫了一個示例程序,該程序的功能非常相似。 它使用OpenCL來計算mandelbrot分形,然后使用OpenGL在QGLWidget繪制它。 源代碼在這里: https : //github.com/kylelutz/compute/blob/master/example/mandelbrot.cpp

希望能有所幫助。

就像上面我在評論中指出的那樣,我發現我的問題與openGL的紋理定義有關。 由於我在openCL內核中使用了write_imageui,因此必須按以下方式定義openGL紋理:

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8UI, width, height, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, NULL);

從那時起,我花了一些時間創建了一個使用openGL / openCL互操作和線程化QGLWidgets的示例程序。 您可以在http://www.krazer.com/?p=109上閱讀我對此的評論,和/或可以從github.com獲取源代碼。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM