在imageStore()之后为3D纹理生成MipMap级别

时间:2018-07-26 20:56:56

标签: c++ opengl segmentation-fault textures mipmaps

我想创建3D纹理,将最低(级别0)的mipmap级别设置为在着色器中生成的某些数据,然后自动填充其余的mipmap级别。

我创建纹理如下:

//Initialize texture dimensions
width = w;
height = h;
depth = d;
//set the texture rendering target, always GL_TEXTURE3D for 3D images
target = GL_TEXTURE_3D;
//Create the texture
glGenTextures(1, &textureID);
glBindTexture(target, textureID);
glObjectLabel(GL_TEXTURE, textureID, -1, "\"3D Texture\"");
//Set the texture sampling parameters
glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
glTexParameteri(target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_BORDER);
glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
//Allocate VRAM storage for the texture
vector<GLbyte> empty = vector<GLbyte>(width*height*depth*(32));
glTexImage3D(target, 0, GL_RGBA8, width, height, depth, 0,
    GL_RGBA, GL_FLOAT, empty.data());

然后我使用imageStore在着色器中写入它(按LOD 0的预期工作)。

然后我尝试生成这样的mipmap级别:

glDrawArrays(GL_TRIANGLE_STRIP,0,4);
glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
glGenerateTextureMipmap(textureID);

但是,这会导致在glGenerateTextureMipmap()处产生分段错误。

创建纹理时我是否在内存屏障上缺少了一点?或者我没有分配足够的内存?我在做什么错了?

1 个答案:

答案 0 :(得分:1)

您以错误的方式使用glMemoryBarrier。您应该使用此功能的位域是您要使用结果的方式。对于生成Mipmap,无需使用内存屏障。

您正在使用glGenerateTextureMipmap,但没有使用glCreateTextures。为什么只想有时使用DSA。到处使用DSA或不使用它(glTextureParameteri,glTextureStorage3D ...也会发生这种情况)。

您正在使用glTexImage3D,请改用glTextureStorage3D。它将为您节省“无用”向量的构建

您正在使用非Mipmap过滤,因此请使用GL_NEAREST_MIPMAP_NEAREST之类的Mipmap过滤。我不知道是否是崩溃的原因,但这是第一个想法。

告诉我们更正代码时会发生什么;)。 如果它告诉您任何信息,也许您可​​以给我们提供ARB_DEBUG_OUTPUT的输出。


关于崩溃,看来使用glTexStorage3D可以解决问题。我没有证据,我可能错了,但是我怀疑这种工作方式: glTexImage3D不分配内存,而是使用纹理进行分配。 (这就是为什么我更喜欢Vulkan的原因,因为它很明显)。

因此,当您在没有glTexImage3D的情况下执行glGenerateMipmap3D时,会发生以下情况:

使用glTexImage3D:说我们需要此尺寸的图像。使用texture:driver可以看到不需要进行映射,因此尽管GL_TEXTURE_MAX_LEVEL它也只分配一个驱动程序。调用generateMipmap:崩溃,因为驱动程序尝试到达尚未分配的其他层

第二种方式,在使用前先使用generateMipmap:

glTexImage3D + generateMipmap:我需要一张具有此大小的图像,且带有mipmap。使用它时,驱动程序会看到您确实需要所有图层,因此它将分配所需的图层。

在使用glTextureStorage3D时,您明确要求各层,因此当驱动程序进行分配时,它将分配所有内容,而不仅仅是一个