Merge pull request #106200 from BlueCube3310/image-16-u16

Image: Implement 16-bit unorm and uint formats
This commit is contained in:
Thaddeus Crews 2025-09-23 12:08:46 -05:00
commit cd3a6c88fd
No known key found for this signature in database
GPG key ID: 8C6E5FEB5FC03CCC
13 changed files with 914 additions and 63 deletions

View file

@ -351,6 +351,40 @@ static Error get_src_texture_format(Image *r_img, RD::DataFormat &r_format) {
r_format = RD::DATA_FORMAT_E5B9G9R9_UFLOAT_PACK32;
break;
case Image::FORMAT_R16:
r_format = RD::DATA_FORMAT_R16_UNORM;
break;
case Image::FORMAT_RG16:
r_format = RD::DATA_FORMAT_R16G16_UNORM;
break;
case Image::FORMAT_RGB16:
r_img->convert(Image::FORMAT_RGBA16);
r_format = RD::DATA_FORMAT_R16G16B16A16_UNORM;
break;
case Image::FORMAT_RGBA16:
r_format = RD::DATA_FORMAT_R16G16B16A16_UNORM;
break;
case Image::FORMAT_R16I:
r_format = RD::DATA_FORMAT_R16_UINT;
break;
case Image::FORMAT_RG16I:
r_format = RD::DATA_FORMAT_R16G16_UINT;
break;
case Image::FORMAT_RGB16I:
r_img->convert(Image::FORMAT_RGBA16I);
r_format = RD::DATA_FORMAT_R16G16B16A16_UINT;
break;
case Image::FORMAT_RGBA16I:
r_format = RD::DATA_FORMAT_R16G16B16A16_UINT;
break;
default: {
return ERR_UNAVAILABLE;
}

View file

@ -74,6 +74,7 @@ enum DDSFourCC {
DDFCC_BC5U = PF_FOURCC("BC5U"),
DDFCC_A2XY = PF_FOURCC("A2XY"),
DDFCC_DX10 = PF_FOURCC("DX10"),
DDFCC_RGBA16 = 36,
DDFCC_R16F = 111,
DDFCC_RG16F = 112,
DDFCC_RGBA16F = 113,
@ -87,14 +88,20 @@ enum DXGIFormat {
DXGI_R32G32B32A32_FLOAT = 2,
DXGI_R32G32B32_FLOAT = 6,
DXGI_R16G16B16A16_FLOAT = 10,
DXGI_R16G16B16A16_UNORM = 11,
DXGI_R16G16B16A16_UINT = 12,
DXGI_R32G32_FLOAT = 16,
DXGI_R10G10B10A2_UNORM = 24,
DXGI_R8G8B8A8_UNORM = 28,
DXGI_R8G8B8A8_UNORM_SRGB = 29,
DXGI_R16G16_FLOAT = 34,
DXGI_R16G16_UNORM = 35,
DXGI_R16G16_UINT = 36,
DXGI_R32_FLOAT = 41,
DXGI_R8G8_UNORM = 49,
DXGI_R16_FLOAT = 54,
DXGI_R16_UNORM = 56,
DXGI_R16_UINT = 57,
DXGI_R8_UNORM = 61,
DXGI_A8_UNORM = 65,
DXGI_R9G9B9E5 = 67,
@ -127,6 +134,12 @@ enum DDSFormat {
DDS_BC6U,
DDS_BC6S,
DDS_BC7,
DDS_R16,
DDS_RG16,
DDS_RGBA16,
DDS_R16I,
DDS_RG16I,
DDS_RGBA16I,
DDS_R16F,
DDS_RG16F,
DDS_RGBA16F,
@ -180,6 +193,12 @@ static const DDSFormatInfo dds_format_info[DDS_MAX] = {
{ "BC6UF", true, 4, 16, Image::FORMAT_BPTC_RGBFU },
{ "BC6SF", true, 4, 16, Image::FORMAT_BPTC_RGBF },
{ "BC7", true, 4, 16, Image::FORMAT_BPTC_RGBA },
{ "R16", false, 1, 2, Image::FORMAT_R16 },
{ "RG16", false, 1, 4, Image::FORMAT_RG16 },
{ "RGBA16", false, 1, 8, Image::FORMAT_RGBA16 },
{ "R16I", false, 1, 2, Image::FORMAT_R16I },
{ "RG16I", false, 1, 4, Image::FORMAT_RG16I },
{ "RGBA16I", false, 1, 8, Image::FORMAT_RGBA16I },
{ "R16F", false, 1, 2, Image::FORMAT_RH },
{ "RG16F", false, 1, 4, Image::FORMAT_RGH },
{ "RGBA16F", false, 1, 8, Image::FORMAT_RGBAH },

View file

@ -67,6 +67,7 @@ DDSFormatType _dds_format_get_type(DDSFormat p_format) {
case DDS_R32F:
case DDS_RG32F:
case DDS_RGBA32F:
case DDS_RGBA16:
return DDFT_FOURCC;
case DDS_BC6S:
@ -74,6 +75,9 @@ DDSFormatType _dds_format_get_type(DDSFormat p_format) {
case DDS_BC7:
case DDS_RGB9E5:
case DDS_RGB32F:
case DDS_R16I:
case DDS_RG16I:
case DDS_RGBA16I:
return DDFT_DXGI;
default:
@ -151,6 +155,24 @@ DDSFormat _image_format_to_dds_format(Image::Format p_image_format) {
case Image::FORMAT_BPTC_RGBA: {
return DDS_BC7;
}
case Image::FORMAT_R16: {
return DDS_R16;
}
case Image::FORMAT_RG16: {
return DDS_RG16;
}
case Image::FORMAT_RGBA16: {
return DDS_RGBA16;
}
case Image::FORMAT_R16I: {
return DDS_R16I;
}
case Image::FORMAT_RG16I: {
return DDS_RG16I;
}
case Image::FORMAT_RGBA16I: {
return DDS_RGBA16I;
}
default: {
return DDS_MAX;
}
@ -181,6 +203,8 @@ uint32_t _image_format_to_fourcc_format(Image::Format p_format) {
return DDFCC_RG16F;
case Image::FORMAT_RGBAH:
return DDFCC_RGBA16F;
case Image::FORMAT_RGBA16:
return DDFCC_RGBA16;
default:
return 0;
@ -221,6 +245,18 @@ uint32_t _image_format_to_dxgi_format(Image::Format p_format) {
return DXGI_R16G16B16A16_FLOAT;
case Image::FORMAT_RGBE9995:
return DXGI_R9G9B9E5;
case Image::FORMAT_R16:
return DXGI_R16_UNORM;
case Image::FORMAT_RG16:
return DXGI_R16G16_UNORM;
case Image::FORMAT_RGBA16:
return DXGI_R16G16B16A16_UNORM;
case Image::FORMAT_R16I:
return DXGI_R16_UINT;
case Image::FORMAT_RG16I:
return DXGI_R16G16_UINT;
case Image::FORMAT_RGBA16I:
return DXGI_R16G16B16A16_UINT;
default:
return 0;
@ -276,6 +312,20 @@ void _get_dds_pixel_bitmask(Image::Format p_format, uint32_t &r_bit_count, uint3
r_blue_mask = 0x1f;
r_alpha_mask = 0;
} break;
case Image::FORMAT_R16: {
r_bit_count = 16;
r_red_mask = 0xffff;
r_green_mask = 0;
r_blue_mask = 0;
r_alpha_mask = 0;
} break;
case Image::FORMAT_RG16: {
r_bit_count = 32;
r_red_mask = 0xffff;
r_green_mask = 0xffff0000;
r_blue_mask = 0;
r_alpha_mask = 0;
} break;
default: {
r_bit_count = 0;

View file

@ -47,6 +47,12 @@ DDSFormat _dxgi_to_dds_format(uint32_t p_dxgi_format) {
case DXGI_R16G16B16A16_FLOAT: {
return DDS_RGBA16F;
}
case DXGI_R16G16B16A16_UNORM: {
return DDS_RGBA16;
}
case DXGI_R16G16B16A16_UINT: {
return DDS_RGBA16I;
}
case DXGI_R32G32_FLOAT: {
return DDS_RG32F;
}
@ -60,6 +66,12 @@ DDSFormat _dxgi_to_dds_format(uint32_t p_dxgi_format) {
case DXGI_R16G16_FLOAT: {
return DDS_RG16F;
}
case DXGI_R16G16_UNORM: {
return DDS_RG16;
}
case DXGI_R16G16_UINT: {
return DDS_RG16I;
}
case DXGI_R32_FLOAT: {
return DDS_R32F;
}
@ -70,6 +82,12 @@ DDSFormat _dxgi_to_dds_format(uint32_t p_dxgi_format) {
case DXGI_R16_FLOAT: {
return DDS_R16F;
}
case DXGI_R16_UNORM: {
return DDS_R16;
}
case DXGI_R16_UINT: {
return DDS_R16I;
}
case DXGI_R8G8_UNORM: {
return DDS_LUMINANCE_ALPHA;
}
@ -550,6 +568,9 @@ static Vector<Ref<Image>> _dds_load_images_from_buffer(Ref<FileAccess> p_f, DDSF
case DDFCC_A2XY: {
r_dds_format = DDS_ATI2;
} break;
case DDFCC_RGBA16: {
r_dds_format = DDS_RGBA16;
} break;
case DDFCC_R16F: {
r_dds_format = DDS_R16F;
} break;
@ -630,6 +651,10 @@ static Vector<Ref<Image>> _dds_load_images_from_buffer(Ref<FileAccess> p_f, DDSF
}
}
if (format_rgb_bits == 32 && format_red_mask == 0xffff && format_green_mask == 0xffff0000) {
r_dds_format = DDS_RG16;
}
} else {
// Other formats.
if (format_flags & DDPF_ALPHAONLY && format_rgb_bits == 8 && format_alpha_mask == 0xff) {
@ -653,6 +678,8 @@ static Vector<Ref<Image>> _dds_load_images_from_buffer(Ref<FileAccess> p_f, DDSF
// Without alpha.
if (format_rgb_bits == 8 && format_red_mask == 0xff) {
r_dds_format = DDS_LUMINANCE;
} else if (format_rgb_bits == 16 && format_red_mask == 0xffff) {
r_dds_format = DDS_R16;
}
}
}

View file

@ -186,6 +186,30 @@ static Ref<Image> load_from_file_access(Ref<FileAccess> f, Error *r_error) {
case GL_RGB9_E5:
format = Image::FORMAT_RGBE9995;
break;
case GL_R16:
format = Image::FORMAT_R16;
break;
case GL_RG16:
format = Image::FORMAT_RG16;
break;
case GL_RGB16:
format = Image::FORMAT_RGB16;
break;
case GL_RGBA16:
format = Image::FORMAT_RGBA16;
break;
case GL_R16UI:
format = Image::FORMAT_R16I;
break;
case GL_RG16UI:
format = Image::FORMAT_RG16I;
break;
case GL_RGB16UI:
format = Image::FORMAT_RGB16I;
break;
case GL_RGBA16UI:
format = Image::FORMAT_RGBA16I;
break;
case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
format = Image::FORMAT_DXT1;
@ -382,6 +406,30 @@ static Ref<Image> load_from_file_access(Ref<FileAccess> f, Error *r_error) {
case VK_FORMAT_E5B9G9R9_UFLOAT_PACK32:
format = Image::FORMAT_RGBE9995;
break;
case VK_FORMAT_R16_UNORM:
format = Image::FORMAT_R16;
break;
case VK_FORMAT_R16G16_UNORM:
format = Image::FORMAT_RG16;
break;
case VK_FORMAT_R16G16B16_UNORM:
format = Image::FORMAT_RGB16;
break;
case VK_FORMAT_R16G16B16A16_UNORM:
format = Image::FORMAT_RGBA16;
break;
case VK_FORMAT_R16_UINT:
format = Image::FORMAT_R16I;
break;
case VK_FORMAT_R16G16_UINT:
format = Image::FORMAT_RG16I;
break;
case VK_FORMAT_R16G16B16_UINT:
format = Image::FORMAT_RGB16I;
break;
case VK_FORMAT_R16G16B16A16_UINT:
format = Image::FORMAT_RGBA16I;
break;
case VK_FORMAT_BC1_RGB_UNORM_BLOCK:
case VK_FORMAT_BC1_RGBA_UNORM_BLOCK:
format = Image::FORMAT_DXT1;