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
13 changed files with 914 additions and 63 deletions

View File

@ -2324,6 +2324,98 @@ Ref<Image> TextureStorage::_validate_texture_format(const Ref<Image> &p_image, T
r_format.swizzle_a = RD::TEXTURE_SWIZZLE_A;
} break; // astc 8x8 HDR
case Image::FORMAT_R16: {
if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_R16_UNORM, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) {
r_format.format = RD::DATA_FORMAT_R16_UNORM;
} else {
// Not supported, reconvert.
r_format.format = RD::DATA_FORMAT_R32_SFLOAT;
image->convert(Image::FORMAT_RF);
}
r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
r_format.swizzle_g = RD::TEXTURE_SWIZZLE_ZERO;
r_format.swizzle_b = RD::TEXTURE_SWIZZLE_ZERO;
r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE;
} break; // unorm16
case Image::FORMAT_RG16: {
if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_R16G16_UNORM, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) {
r_format.format = RD::DATA_FORMAT_R16G16_UNORM;
} else {
// Not supported, reconvert.
r_format.format = RD::DATA_FORMAT_R32G32_SFLOAT;
image->convert(Image::FORMAT_RGF);
}
r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G;
r_format.swizzle_b = RD::TEXTURE_SWIZZLE_ZERO;
r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE;
} break;
case Image::FORMAT_RGB16: {
if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_R16G16B16_UNORM, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) {
r_format.format = RD::DATA_FORMAT_R16G16B16_UNORM;
} else {
// Not supported, reconvert.
if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_R16G16B16A16_UNORM, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) {
r_format.format = RD::DATA_FORMAT_R16G16B16A16_UNORM;
image->convert(Image::FORMAT_RGBA16);
} else {
r_format.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT;
image->convert(Image::FORMAT_RGBAF);
}
}
r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G;
r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B;
r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE;
} break;
case Image::FORMAT_RGBA16: {
if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_R16G16B16A16_UNORM, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) {
r_format.format = RD::DATA_FORMAT_R16G16B16A16_UNORM;
} else {
// Not supported, reconvert.
r_format.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT;
image->convert(Image::FORMAT_RGBAF);
}
r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G;
r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B;
r_format.swizzle_a = RD::TEXTURE_SWIZZLE_A;
} break;
case Image::FORMAT_R16I: {
r_format.format = RD::DATA_FORMAT_R16_UINT;
r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
r_format.swizzle_g = RD::TEXTURE_SWIZZLE_ZERO;
r_format.swizzle_b = RD::TEXTURE_SWIZZLE_ZERO;
r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE;
} break; // uint16
case Image::FORMAT_RG16I: {
r_format.format = RD::DATA_FORMAT_R16G16_UINT;
r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G;
r_format.swizzle_b = RD::TEXTURE_SWIZZLE_ZERO;
r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE;
} break;
case Image::FORMAT_RGB16I: {
//this format is not mandatory for specification, check if supported first
if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_R16G16B16_UINT, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) {
r_format.format = RD::DATA_FORMAT_R16G16B16_UINT;
} else {
//not supported, reconvert
r_format.format = RD::DATA_FORMAT_R16G16B16A16_UINT;
image->convert(Image::FORMAT_RGBA16I);
}
r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G;
r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B;
r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE;
} break;
case Image::FORMAT_RGBA16I: {
r_format.format = RD::DATA_FORMAT_R16G16B16A16_UINT;
r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G;
r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B;
r_format.swizzle_a = RD::TEXTURE_SWIZZLE_A;
} break;
default: {
}
@ -2716,7 +2808,7 @@ void TextureStorage::_texture_format_from_rd(RD::DataFormat p_rd_format, Texture
r_format.swizzle_a = RD::TEXTURE_SWIZZLE_A;
} break; // astc 8x8
case RD::DATA_FORMAT_D16_UNORM: {
r_format.image_format = Image::FORMAT_RH;
r_format.image_format = Image::FORMAT_R16;
r_format.rd_format = RD::DATA_FORMAT_D16_UNORM;
r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
r_format.swizzle_g = RD::TEXTURE_SWIZZLE_ZERO;
@ -2731,6 +2823,70 @@ void TextureStorage::_texture_format_from_rd(RD::DataFormat p_rd_format, Texture
r_format.swizzle_b = RD::TEXTURE_SWIZZLE_ZERO;
r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE;
} break;
case RD::DATA_FORMAT_R16_UNORM: {
r_format.image_format = Image::FORMAT_R16;
r_format.rd_format = RD::DATA_FORMAT_R16_UNORM;
r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
r_format.swizzle_g = RD::TEXTURE_SWIZZLE_ZERO;
r_format.swizzle_b = RD::TEXTURE_SWIZZLE_ZERO;
r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE;
} break; // unorm16
case RD::DATA_FORMAT_R16G16_UNORM: {
r_format.image_format = Image::FORMAT_RG16;
r_format.rd_format = RD::DATA_FORMAT_R16G16_UNORM;
r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G;
r_format.swizzle_b = RD::TEXTURE_SWIZZLE_ZERO;
r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE;
} break;
case RD::DATA_FORMAT_R16G16B16_UNORM: {
r_format.image_format = Image::FORMAT_RGB16;
r_format.rd_format = RD::DATA_FORMAT_R16G16B16_UNORM;
r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G;
r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B;
r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE;
} break;
case RD::DATA_FORMAT_R16G16B16A16_UNORM: {
r_format.image_format = Image::FORMAT_RGBA16;
r_format.rd_format = RD::DATA_FORMAT_R16G16B16A16_UNORM;
r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G;
r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B;
r_format.swizzle_a = RD::TEXTURE_SWIZZLE_A;
} break;
case RD::DATA_FORMAT_R16_UINT: {
r_format.image_format = Image::FORMAT_R16I;
r_format.rd_format = RD::DATA_FORMAT_R16_UINT;
r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
r_format.swizzle_g = RD::TEXTURE_SWIZZLE_ZERO;
r_format.swizzle_b = RD::TEXTURE_SWIZZLE_ZERO;
r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE;
} break; // uint16
case RD::DATA_FORMAT_R16G16_UINT: {
r_format.image_format = Image::FORMAT_RG16I;
r_format.rd_format = RD::DATA_FORMAT_R16G16_UINT;
r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G;
r_format.swizzle_b = RD::TEXTURE_SWIZZLE_ZERO;
r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE;
} break;
case RD::DATA_FORMAT_R16G16B16_UINT: {
r_format.image_format = Image::FORMAT_RGB16I;
r_format.rd_format = RD::DATA_FORMAT_R16G16B16_UINT;
r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G;
r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B;
r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE;
} break;
case RD::DATA_FORMAT_R16G16B16A16_UINT: {
r_format.image_format = Image::FORMAT_RGBA16I;
r_format.rd_format = RD::DATA_FORMAT_R16G16B16A16_UINT;
r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G;
r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B;
r_format.swizzle_a = RD::TEXTURE_SWIZZLE_A;
} break;
default: {
ERR_FAIL_MSG("Unsupported image format");