From 4942964e2fb29338f4c8721d3e2877bdc2065dc7 Mon Sep 17 00:00:00 2001 From: Stenzek Date: Tue, 19 Dec 2023 21:14:00 +1000 Subject: [PATCH] OpenGLDevice: Fix texture creation issues w/o texture storage --- src/util/opengl_texture.cpp | 82 ++++++++++++++++++++++++------------- 1 file changed, 53 insertions(+), 29 deletions(-) diff --git a/src/util/opengl_texture.cpp b/src/util/opengl_texture.cpp index c2e0248b6..d487442fb 100644 --- a/src/util/opengl_texture.cpp +++ b/src/util/opengl_texture.cpp @@ -140,45 +140,69 @@ bool OpenGLTexture::Create(u32 width, u32 height, u32 layers, u32 levels, u32 sa } else { - if (UseTextureStorage(false)) + const bool use_texture_storage = UseTextureStorage(false); + if (use_texture_storage) { if (layers > 1) glTexStorage3D(target, levels, gl_internal_format, width, height, layers); else glTexStorage2D(target, levels, gl_internal_format, width, height); + } + + if (!use_texture_storage || data) + { + const u32 pixel_size = GetPixelSize(format); + const u32 alignment = ((data_pitch % 4) == 0) ? 4 : (((data_pitch % 2) == 0) ? 2 : 1); + if (data) + { + glPixelStorei(GL_UNPACK_ROW_LENGTH, data_pitch / pixel_size); + if (alignment != 4) + glPixelStorei(GL_UNPACK_ALIGNMENT, alignment); + } + + const u8* data_ptr = static_cast(data); + u32 current_width = width; + u32 current_height = height; + for (u32 i = 0; i < levels; i++) + { + if (use_texture_storage) + { + if (layers > 1) + glTexSubImage3D(target, i, 0, 0, 0, current_width, current_height, layers, gl_format, gl_type, data_ptr); + else + glTexSubImage2D(target, i, 0, 0, current_width, current_height, gl_format, gl_type, data_ptr); + } + else + { + if (layers > 1) + glTexImage3D(target, i, gl_internal_format, current_width, current_height, layers, 0, gl_format, gl_type, + data_ptr); + else + glTexImage2D(target, i, gl_internal_format, current_width, current_height, 0, gl_format, gl_type, data_ptr); + } + + if (data_ptr) + data_ptr += data_pitch * current_width; + + current_width = (current_width > 1) ? (current_width / 2u) : current_width; + current_height = (current_height > 1) ? (current_height / 2u) : current_height; + + // TODO: Incorrect assumption. + data_pitch = pixel_size * current_width; + } if (data) { - glPixelStorei(GL_UNPACK_ROW_LENGTH, data_pitch / GetPixelSize(format)); - - // TODO: Fix data for mipmaps here. - if (layers > 1) - glTexSubImage3D(target, 0, 0, 0, 0, width, height, layers, gl_format, gl_type, data); - else - glTexSubImage2D(target, 0, 0, 0, width, height, gl_format, gl_type, data); - + if (alignment != 4) + glPixelStorei(GL_UNPACK_ALIGNMENT, 4); glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); } } - else + + if (!use_texture_storage) { - if (data) - glPixelStorei(GL_UNPACK_ROW_LENGTH, data_pitch / GetPixelSize(format)); - - for (u32 i = 0; i < levels; i++) - { - // TODO: Fix data pointer here. - if (layers > 1) - glTexImage3D(target, i, gl_internal_format, width, height, layers, 0, gl_format, gl_type, data); - else - glTexImage2D(target, i, gl_internal_format, width, height, 0, gl_format, gl_type, data); - } - - if (data) - glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); - glTexParameteri(target, GL_TEXTURE_BASE_LEVEL, 0); - glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, levels); + glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, levels - 1); } } @@ -400,9 +424,9 @@ std::unique_ptr OpenGLDevice::CreateSampler(const GPUSampler::Config glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, filters[mipmap_on_off][static_cast(config.mip_filter.GetValue())] [static_cast(config.min_filter.GetValue())]); - glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, - filters[mipmap_on_off][static_cast(config.mip_filter.GetValue())] - [static_cast(config.mag_filter.GetValue())]); + glSamplerParameteri( + sampler, GL_TEXTURE_MAG_FILTER, + filters[0][static_cast(config.mip_filter.GetValue())][static_cast(config.mag_filter.GetValue())]); glSamplerParameterf(sampler, GL_TEXTURE_MIN_LOD, static_cast(config.min_lod)); glSamplerParameterf(sampler, GL_TEXTURE_MAX_LOD, static_cast(config.max_lod)); glSamplerParameterfv(sampler, GL_TEXTURE_BORDER_COLOR, config.GetBorderFloatColor().data());