2016-02-03 8 views
8

GPGPUをよりよく理解するために、小さなフロート配列をOpenGL ES 2.0テクスチャとしてサブミットして読み込もうとしています。私はこれをTI OMAP3 ARM SoCのSGX 530 GPUで試行しています。私は、このガイドの次きたOpenGL ES 2 GPGPUテストのテクスチャとデータの抽出方法

enter link description here

私のコードは、現在作成して移入2つのフロートアレイをし、このようなシェーダー「通過」を作成します:私は、その後にしよう

void GLWidget::initializeGL() 
{ 

    // Max texture size in each direction 
    int maxSize; 
    glGetIntegerv(GL_MAX_TEXTURE_SIZE,&maxSize); 
    texSize = sqrt(maxSize); 
    texSize = 2; 
    qDebug() << "GL_MAX_TEXTURE_SIZE " << maxSize << " SQRT " << texSize; 

    // Define input and output arrays of RGBA format with each channel being u8 
    m_Format = 4; 
    dataX = (quint8*)malloc(m_Format*texSize*texSize*sizeof(quint8)); 
    dataY = (quint8*)malloc(m_Format*texSize*texSize*sizeof(quint8)); 

    // Setup some dummy data 
    int arraySize = m_Format*texSize*texSize; 
    qDebug() << "Array Size: " << arraySize; 
    for (int i = 0; i < arraySize ; i++) { 
     dataX[i] = i; 
    } 

    for (int i = 0; i < arraySize ; i++) { 
     dataY[i] = 0; 
    } 

    QGLShader *vshader = new QGLShader(QGLShader::Vertex); 
    const char *vsrc = 
      "attribute highp vec4 vertex;\n" 
      "attribute highp vec4 texCoord;\n" 
      "varying vec2 texc;\n" 
      "void main(void)\n" 
      "{\n" 
      " gl_Position = vertex;\n" 
      " texc = texCoord.xy;\n" 
      "}\n"; 
    vshader->compileSourceCode(vsrc); 

    QGLShader *fshader = new QGLShader(QGLShader::Fragment); 
    const char *fsrc = 
      "varying highp vec2 texc;\n" 
      "uniform sampler2D tex;\n" 
      "void main(void)\n" 
      "{\n" 
      " gl_FragColor = texture2D(tex, texc);\n" 
      "}\n"; 
    fshader->compileSourceCode(fsrc); 

    program.addShader(vshader); 
    program.addShader(fshader); 
    program.link(); 

    vertexAttr = program.attributeLocation("vertex"); 
    texCoordAttr = program.attributeLocation("texCoord"); 
    textureUniform = program.uniformLocation("tex"); 

} 

、GPUにテクスチャを提出するフレームバッファにそれをレンダリングして、このようにそれを読み返す:

void GLWidget::renderToScene() 
{ 

    // Bind and configure a texture 
    glActiveTexture(GL_TEXTURE0); 
    glGenTextures(1, &m_hTexture); 
    glBindTexture(GL_TEXTURE_2D, m_hTexture); 
    glUniform1i(textureUniform, 0); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texSize, texSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, dataX); // Allocate buffer to hold RGBA with 8 bytes each 

    // Generate handles for Frame Buffer Object 
    glGenFramebuffers(1, &m_hFBO); 

    // Switch the render target to the current FBO to update the texture map 
    glBindFramebuffer(GL_FRAMEBUFFER, m_hFBO); 

    qDebug() << "Data before roundtrip:"; 
    int arraySize = m_Format*texSize*texSize; 
    for (int i = 0 ; i < arraySize ; i++) 
     qDebug() << dataX[i]; 

    // FBO attachment is complete? 
    if (glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE) 
    { 

     qDebug() << "Frame buffer is present..."; 
     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_hTexture, 0); 
     //glTexSubImage2D(GL_TEXTURE_2D,0,0,0,texSize,texSize, GL_RGBA,GL_UNSIGNED_BYTE,dataX); // pixel data is RGBA and each channel u8 

     static const GLfloat squareVertices[] = { 
      -1.0f, -1.0f, 
      1.0f, -1.0f, 
      -1.0f, 1.0f, 
      1.0f, 1.0f, 
     }; 

     static const GLfloat textureVertices[] = { 
      1.0f, 1.0f, 
      1.0f, 0.0f, 
      0.0f, 1.0f, 
      0.0f, 0.0f, 
     }; 

     // ensure no VBOs or IBOs are bound 
     glBindBuffer(GL_ARRAY_BUFFER, 0); 
     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); 

     // Set pointers to the arrays 
     glVertexAttribPointer(ATTRIB_VERTEX, 2, GL_FLOAT, 0, 0, squareVertices); 
     glEnableVertexAttribArray(ATTRIB_VERTEX); 
     glVertexAttribPointer(ATTRIB_TEXTUREPOSITON, 2, GL_FLOAT, 0, 0, textureVertices); 
     glEnableVertexAttribArray(ATTRIB_TEXTUREPOSITON); 

     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 

     glDisableVertexAttribArray(ATTRIB_VERTEX); 
     glDisableVertexAttribArray(ATTRIB_TEXTUREPOSITON); 

    } 

    qDebug() << "Zero data:"; 
    for (int i = 0; i < arraySize ; i++) 
     qDebug() << dataY[i]; 

    // GPGPU Extract 
    glReadPixels(0, 0, texSize, texSize, GL_RGBA,GL_UNSIGNED_BYTE,dataY); 

    // print out results 
    qDebug() << "Data after roundtrip:"; 
    for (int i = 0; i < arraySize ; i++) 
     qDebug() << dataY[i]; 

    // Unbind the FBO so rendering will return to the main buffer. 
    glBindFramebuffer(GL_FRAMEBUFFER, 0); 

    qDebug() << "Done..."; 
    sleep(60000); 

} 

ドローコールがどのように見えますこの:

void GLWidget::draw() { 

    glClearColor(0.1f, 0.1f, 0.2f, 1.0f); 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

    glFrontFace(GL_CW); 
    glCullFace(GL_FRONT); 
    glEnable(GL_CULL_FACE); 
    glEnable(GL_DEPTH_TEST); 

    // Draw 
    program.bind(); 
    renderToScene(); 
    program.release(); 

    glDisable(GL_DEPTH_TEST); 
    glDisable(GL_CULL_FACE); 

    swapBuffers(); 

} 

すべてがコンパイルおよび実行されますが、私のデータ出力は次のようになります。

Found SGX/MBX driver, enabling FullClearOnEveryFrame 
Found v1.4 driver, enabling brokenTexSubImage 
Found non-Nokia v1.4 driver, enabling brokenFBOReadBack 
GL_MAX_TEXTURE_SIZE 2048 SQRT 2 
Array Size: 16 
Data before roundtrip: 
0 
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
Zero data: 
0 
0 
0 
0 
0 
0 
0 
0 
0 
0 
0 
0 
0 
0 
0 
0 
Data after roundtrip: 
0 
0 
0 
0 
0 
0 
0 
0 
0 
0 
0 
0 
0 
0 
0 
0 
Done... 

はどのように提出することができ、適切に私のテキストを読み戻しますか?ありがとう!

答えて

1

私は、GPUにテクスチャを提出し、この

のようにそれをリードバックしようと[...]

だから、私は戻ってからバッファを「取得」わけではないことは明らかですOpenGL。 glReadPixelsを使用してdataY配列にテクスチャを読み戻しているので、1.5が含まれていると思います。

なぜあなたが読んでいるバックバッファではないのですか?

カラーバッファにテクスチャをレンダリングしないので、カラーバッファから読み込むとテクスチャデータが返されることはありません。

元のコードではフレームバッファオブジェクトを使用してテクスチャにカラーバッファとしてアクセスしますが、このシナリオでは全く異なるセマンティックが使用されます(ただし、これはほとんど役に立たないベンチマークです)。実際のES2デバイスのほとんどはGL_OES_framebuffer_object extensionもサポートしているので、概念的にはそれを移植することができます。

+1

FB 2.0のサポートは、ES 2.0では標準です。拡張機能の必要はありません。 –

3

表示されているコードには、テクスチャを使用し、デフォルトのカラーバッファ(glDrawElementsのような呼び出し)にレンダリングする描画呼び出しがありません。 glReadPixelsは、デフォルトのFramebufferから読み込みます。それはGL_COLOR_ATTACHMENT0、フレームバッファのサポート/ nullwsサポート付きTIデバイスの大多数のためではないGL_COLOR_ATTACHMENT0_EXT

を使用してOpenGLES2に変更することができ、あなたは下のリンクでプロファイリングコードを使用することができます。以下のコードは、エッジ検出、色変換、FBOの使用など、いくつかのGPGPUシナリオをテストします。 SGX530 GPUのないSGX540 https://github.com/prabindh/sgxperf/blob/master/sgxperf_gles20_vg.cpp

17ところで、OMAP3生産チップセットは(いた)き、テスト11への呼び出しを参照してください。 SGX540 /変種はOMAP4チップセットで使用されています。 SGX540を使用したOMAP3プロダクションがある場合は非常に幸運でしょう:)ブートローグやPVRドライバのデバッグバージョンで確認できます。

また、どのボード/プラットフォームが使用されているかについても言及してください。

+1

はい、あなたは正しいです:)私はCPUがSGX530とのDM3730です。リンクをありがとう、私はこれをできるだけ早く試みます。 – PhilBot

4

このコードでは多くの問題が発生しています。主なものは、ES 2.0がフロートテクスチャをサポートしていないことです。具体的に:

  • GL_FLOATglTexImage2D()glTexSubImage2D()タイプ引数として有効ではありません。これは、GL_UNSIGNED_BYTE、またはさまざまなGL_UNSIGNED_SHORT_*オプションの1つである必要があります。
  • すべての実装でサポートglReadPixels()ためのみフォーマット/タイプ組み合わせがGL_RGBA/GL_UNSIGNED_BYTEあります。照会できる2番目の実装依存の組み合わせがあります。
  • すでに指摘されているように、データでテクスチャを塗りつぶして、現在のフレームバッファからデータを読み込もうとしています。したがって、両方の操作で有効な引数が使用されても、データは取得できません。

API呼び出しに有効である可能性のある、または有効でない可能性のある引数を渡すことを盲目的に試みる前に、いくつかのドキュメントを確認することを強くお勧めします。 man pagesは良いスタートです。また、無効な呼び出しを行うとエラーコードを返すglGetError()を使用します。

実装では、探している機能の一部をサポートする拡張機能をサポートできます。例えば。 OES_texture_floatは、floatテクスチャのサポートを追加します。しかし、それらを使用しようとする前に、これらの拡張機能の存在を確認する必要があります。

関連する問題