Я хочу создать трехмерную текстуру, установить самый низкий (уровень 0) уровень мипмапа для некоторых данных, которые генерируются в шейдерах, а затем автоматически заполнить остальные уровни мипмапа.
Я создаю текстуру следующим образом:
//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()
,
Я немного упускаю барьер памяти или недостаточно выделяю память при создании текстуры? Что я делаю неправильно?
Ты используешь glMemoryBarrier
неправильно. Битовое поле, которое вы должны дать этой функции, является способом, которым вы хотите использовать результат. Для создания mipmap нет необходимости использовать барьер памяти.
Ты используешь glGenerateTextureMipmap
, но вы не используете glCreateTextures
, Почему вы хотите использовать DSA только иногда. Используйте DSA везде или не используйте его (то же самое происходит для glTextureParameteri, glTextureStorage3D …).
Ты используешь glTexImage3D
использовать glTextureStorage3D
вместо. Это спасет вас от построения вашего «бесполезного» вектора
Вы используете не mipmap-фильтрацию, поэтому, пожалуйста, используйте mipmap-фильтрацию, например GL_NEAREST_MIPMAP_NEAREST
, Я не знаю, является ли это причиной аварии, но это первая идея.
Расскажите нам, что произойдет, когда вы исправите код;).
Может быть, вы могли бы дать нам вывод ARB_DEBUG_OUTPUT, если он говорит вам что-нибудь.
Насчет крушения, похоже, что использовать glTexStorage3D
решает проблему. У меня нет доказательств, и я могу ошибаться, но я подозреваю, что этот вид работы:
glTexImage3D
не выделяет память, это использование текстуры, которая делает выделение. (Вот почему я предпочитаю Vulkan, потому что это явно).
поэтому, когда вы делаете glTexImage3D
без glGenerateMipmap3D
вот что происходит:
использование glTexImage3D
Скажем, нам нужно изображение в этом размере. Используйте текстуру: драйвер видит, что нет необходимости в отображении, поэтому он выделяет только один драйвер, несмотря на GL_TEXTURE_MAX_LEVEL. Вызвать generateMipmap: сбой, потому что драйвер пытается достичь других слоев, которые не были выделены
Второй способ, используйте generateMipmap перед использованием:
glTexImage3D
+ generateMipmap
: Мне нужно одно изображение такого размера с помощью mipmap. Когда вы используете его, драйвер видит, что вам действительно нужны все слои, поэтому он выделит нужные слои.
Когда вы используете glTextureStorage3D
вы явно запрашиваете слои, поэтому, когда драйвер выполняет распределение, он будет распределять все, а не только один
Других решений пока нет …