无法从 GPU 复制到 CPU (OpenGL)

Posted

技术标签:

【中文标题】无法从 GPU 复制到 CPU (OpenGL)【英文标题】:Can't copy from GPU to CPU (OpenGL) 【发布时间】:2012-12-02 15:44:53 【问题描述】:

这是我的纹理类:

struct GPUAllocation 
    uint ID,VectorType,DataType,Width,Height,Format,IntFormat;
    //ID is the output from glGen* and Format is the format of the texture and IntFormat
    //is the Internal Format of this texture. (Width and height and too obvious)
    //DataType is like GL_FLOAT...
    bool isFinalized;
    GPUAllocation(uint vectorType,uint dataType,uint width,uint height);
    void SetSlot(int n);
    void Finalize();
    ~GPUAllocation();
;

从此纹理复制到 RAM 的代码:

void memcpy(GPUAllocation src,void* dst) 
    glBindTexture(GL_TEXTURE_2D,src.ID); //ID is the output from glGen*
    glTexSubImage2D(GL_TEXTURE_2D,0,0,0,src.Width,src.Height,src.Format,src.DataType,dst);

运行这个函数的代码是:

GPUAllocation gpu_alloc(PCPU_Vector1,PCPU_Float,4096,4096); //I generate Format and IntFormat here.
//The generated format is correct because when I copied from GPU to CPU I didn't got any error
float *cpu_alloc=new float[4096*4096];
memcpy(gpu_alloc,cpu_alloc); //The error occurred here!

发生的错误是1281


编辑: 我发现当我从 GPU 复制到 CPU,然后从 CPU 复制到 GPU 时,我得到了那个错误。如果我首先从 GPU 复制到 CPU,我没有收到任何错误。 从 CPU 复制到 GPU 的函数是:

void memcpy(void* src,GPUAllocation dst) 
    glBindTexture(GL_TEXTURE_2D,dst.ID);
    glGetTexImage(GL_TEXTURE_2D,0,dst.Format,dst.DataType,src);

【问题讨论】:

“当我从 GPU 复制到 CPU,然后从 CPU 复制到 GPU 时,我发现了这个错误。如果我首先从 GPU 复制到 CPU,我没有收到任何错误”。当您调用glTexImage* 时,GL 将在 GPU 上分配存储空间。如果您尝试读取尚未为其分配存储空间的纹理,则会出现错误。顺便说一句,您编写两个memcpy 函数的方式,目标是第一个参数。 :) 【参考方案1】:

glTexSubImage* 函数复制纹理,而不是从。使用glReadPixels 将纹理从 GL 读取到客户端内存。

我也强烈推荐观看Optimized Texture Transfers

PS。错误,当然,glReadPixels 从帧缓冲区读取,而不是从纹理中读取,glGetTexImage 从纹理中读取。

【讨论】:

那么glGetTexImage是什么? 我尝试了另一个glBindTexture(GL_TEXTURE_2D,src.ID); glReadPixels(0,0,src.Width,src.Height,src.Format,src.DataType,dst); 并得到1286 错误...我想我不知道如何使用它:S. @chill:值得注意的是,在 OpenGL-ES 中没有 glGetTexImage 并且确实已经将纹理渲染到帧缓冲区并使用 glReadPixels 检索数据。但是在普通的OpenGL中glGetTexImage当然是首选的方法了。

以上是关于无法从 GPU 复制到 CPU (OpenGL)的主要内容,如果未能解决你的问题,请参考以下文章

从 GPU 复制到 CPU 比从 CPU 复制到 GPU 慢

有没有更好更快的方法来使用推力从 CPU 内存复制到 GPU?

将 2D 纹理阵列的单层从 GPU 复制到 CPU

CUDA与OpenGL互操作

从 ArrayFire 使用 OpenGL

OS X 上的 ViennaCL:无法将数据复制到 GPU