2011-12-29 23 views
1

cudaMalloc()cudaMemcpy()を使用して、デバイス(ビデオ)メモリにビットマップ(イメージ)が既にあるとします。デバイス(ビデオ)メモリから直接現在のウィンドウにビットマップを表示

このビットマップを画面(現在のウィンドウ)に直接表示する最も簡単な方法は何ですか?

GDIのBitBlt()に代わるものがあるはずですが、Direct3D、OpenGL、さらにはGDIのアプローチでも問題ありません。

CUDA SDK(OpenGLバージョン)の例では、CUDAリソースとして登録され、各フレーム(glutDisplayFunc()呼び出し)にマッピング/マッピング解除されるべきデータを保持するバッファ(ピクセルバッファオブジェクト)を使用するテクスチャを使用します。そして、それはちょっとしたものが複雑で、心配していないようです。

+0

「これはすべて、ちょっと複雑で些細なことだと思います」タフ;そういうものだ。 CUDAは何も描画できません。そしてCUDAは小さな世界に住んでいます。何かを描くためには、CUDAの世界から、実際に物を描くことができるものの世界にデータを取得する必要があります。 CUDAデータをOpenGLまたはD3Dオブジェクトに直接生成する方が良いでしょう。 –

+0

はい、私はCUDAがコンピューティングのためだけであることを理解しています。もしあなたが好きなら、CUDAを忘れることができます。主なものは、ビットマップを保持する線形のデバイスメモリのアドレスがあるからです。私が必要とするのは、このビットマップをフレームバッファにビットblitすることだけです。私はDirect2Dがその解決策の一つであると推測していますが、残念ながらWindows 7/Vistaのみでサポートされています。 – AlexP

+0

私は、Direct2Dがそのブリッティング関数で "線形配置されたデバイスメモリ"へのポインタを取っていないことは確かです。これらのポインタを表すオブジェクトを取ります。そのため、変換レイヤーが必要です。ほとんどの描画APIはGPUメモリへのポインタとそれらからのblitを持つだけではありません。そうしても、CUDAポインタが他のAPIで使用されるポインタと同じ種類であるという保証はありません。 –

答えて

1

さて、私自身の質問に答えようとします。 OpenGL経由でビットマップを表示するための簡単な方法があるように見えます。テクスチャ+ピクセルバッファオブジェクトを使用する代わりに、テクスチャフォーマットGL_RGBA8をサポートするcudaGraphicsGLRegisterImage()をCUDA Toolkit 4.0以降使用できます。

例を簡潔にするため、cutilSafeCall()またはエラーチェックはありません。私はOpenGLに関する知識はほとんど持っておらず、お勧めを聞いてうれしいです。

#include <stdio.h> 
#include <string.h> 

#include <GL/glew.h> 
#include <GL/freeglut.h> 

#include <cuda_runtime_api.h> 
#include <cuda_gl_interop.h> 

/* Handles OpenGL-CUDA exchange. */ 
cudaGraphicsResource *cuda_texture; 

/* Registers (+ resizes) CUDA-Texture (aka Renderbuffer). */ 
void resizeTexture(int w, int h) { 
    static GLuint gl_texture = 0; 

    /* Delete old CUDA-Texture. */ 
    if (gl_texture) { 
     cudaGraphicsUnregisterResource(cuda_texture); 
     glDeleteTextures(1, &gl_texture); 
    } else glEnable(GL_TEXTURE_2D); 

    glGenTextures(1, &gl_texture); 
    glBindTexture(GL_TEXTURE_2D, gl_texture); 

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); 

    cudaGraphicsGLRegisterImage(&cuda_texture, gl_texture, GL_TEXTURE_2D, cudaGraphicsMapFlagsWriteDiscard); 
} 

void updateMemDevice(cudaArray *memDevice, int w, int h) { 
    struct Color { 
     unsigned char r, g, b, a; 
    } *memHost = new Color[w*h]; 

    memset(memHost, 128, w*h*4); 
    for (int y = 0; y<h; ++y) { 
     for (int x = 0; x<w; ++x) { 
      Color &c = memHost[y*w + x]; 
      c.r = c.b = 255 * x/w; 
     } 
    } 
    cudaMemcpyToArray(memDevice, 0, 0, memHost, w*h*4, cudaMemcpyHostToDevice); 
    delete [] memHost; 
} 

void editTexture(int w, int h) { 
    cudaGraphicsMapResources(1, &cuda_texture); 
    cudaArray* memDevice; 
    cudaGraphicsSubResourceGetMappedArray(&memDevice, cuda_texture, 0, 0); 
    updateMemDevice(memDevice, w, h); 
    cudaGraphicsUnmapResources(1, &cuda_texture); 
} 


void windowResizeFunc(int w, int h) { 
    glViewport(-w, -h, w*2, h*2); 
} 

void displayFunc() { 
    glBegin(GL_QUADS); 
    glTexCoord2i(0, 0); glVertex2i(0, 0); 
    glTexCoord2i(1, 0); glVertex2i(1, 0); 
    glTexCoord2i(1, 1); glVertex2i(1, 1); 
    glTexCoord2i(0, 1); glVertex2i(0, 1); 
    glEnd(); 

    glFlush(); 
} 


int main(int argc, char *argv[]) { 
    /* Initialize OpenGL context. */ 
    glutInit(&argc, argv); 
    glutInitDisplayMode(GLUT_RGB); 
    glutInitWindowSize(400, 300); 
    glutCreateWindow("Bitmap in Device Memory"); 
    glutReshapeFunc(windowResizeFunc); 
    glutDisplayFunc(displayFunc); 

    glewInit(); 

    cudaGLSetGLDevice(0); 

    int width = 5, height = 5; 
    resizeTexture(width, height); 
    editTexture(width, height); 

    glutMainLoop(); 
    return 0; 
} 
+0

これは、画像をシステムメモリにコピーしてから表示するよりも速いのですか? –

+0

一般的に、私たちがupdateMemDevice()を呼び出さない限り(または可能な限りまれに呼び出す) - はい、これはより高速です。そうでなければ、updateMemDevice()はイメージをシステムメモリ(momHost)からデバイス(memDevice)にコピーします。システムメモリ内の画像は、ビデオカードのジョブであるため、表示するために、要求したかどうかにかかわらず、デバイスのメモリにコピーされます。最も速い方法は、CUDA/OpenCLを使用してデバイスのメモリ自体にイメージを生成することによってシステムメモリをまったく使用しないことです。 – AlexP

関連する問題