Serenity Operating System
at master 294 lines 12 kB view raw
1/* 2 * Copyright (c) 2022, Jelle Raaijmakers <jelle@gmta.nl> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include <LibGL/Image.h> 8 9namespace GL { 10 11ErrorOr<GPU::PixelType> get_validated_pixel_type(GLenum target, GLenum internal_format, GLenum format, GLenum type) 12{ 13 // We accept GL_NONE as target for non-texture related calls (such as `glDrawPixels`) 14 if (target != GL_NONE 15 && target != GL_TEXTURE_1D 16 && target != GL_TEXTURE_2D 17 && target != GL_TEXTURE_3D 18 && target != GL_TEXTURE_1D_ARRAY 19 && target != GL_TEXTURE_2D_ARRAY 20 && target != GL_TEXTURE_CUBE_MAP 21 && target != GL_PROXY_TEXTURE_1D 22 && target != GL_PROXY_TEXTURE_2D 23 && target != GL_PROXY_TEXTURE_3D) 24 return Error::from_errno(GL_INVALID_ENUM); 25 26 // Internal format can be a number between 1 and 4. Symbolic formats were only added with EXT_texture, promoted to core in OpenGL 1.1 27 if (internal_format == 1) 28 internal_format = GL_ALPHA; 29 else if (internal_format == 2) 30 internal_format = GL_LUMINANCE_ALPHA; 31 else if (internal_format == 3) 32 internal_format = GL_RGB; 33 else if (internal_format == 4) 34 internal_format = GL_RGBA; 35 36 if (internal_format != GL_NONE 37 && internal_format != GL_ALPHA 38 && internal_format != GL_ALPHA4 39 && internal_format != GL_ALPHA8 40 && internal_format != GL_ALPHA12 41 && internal_format != GL_ALPHA16 42 && internal_format != GL_COMPRESSED_ALPHA 43 && internal_format != GL_COMPRESSED_LUMINANCE 44 && internal_format != GL_COMPRESSED_LUMINANCE_ALPHA 45 && internal_format != GL_COMPRESSED_INTENSITY 46 && internal_format != GL_COMPRESSED_RGB 47 && internal_format != GL_COMPRESSED_RGBA 48 && internal_format != GL_DEPTH_COMPONENT 49 && internal_format != GL_DEPTH_COMPONENT16 50 && internal_format != GL_DEPTH_COMPONENT24 51 && internal_format != GL_DEPTH_COMPONENT32 52 && internal_format != GL_DEPTH_STENCIL 53 && internal_format != GL_LUMINANCE 54 && internal_format != GL_LUMINANCE4 55 && internal_format != GL_LUMINANCE8 56 && internal_format != GL_LUMINANCE12 57 && internal_format != GL_LUMINANCE16 58 && internal_format != GL_LUMINANCE_ALPHA 59 && internal_format != GL_LUMINANCE4_ALPHA4 60 && internal_format != GL_LUMINANCE6_ALPHA2 61 && internal_format != GL_LUMINANCE8_ALPHA8 62 && internal_format != GL_LUMINANCE12_ALPHA4 63 && internal_format != GL_LUMINANCE12_ALPHA12 64 && internal_format != GL_LUMINANCE16_ALPHA16 65 && internal_format != GL_INTENSITY 66 && internal_format != GL_INTENSITY4 67 && internal_format != GL_INTENSITY8 68 && internal_format != GL_INTENSITY12 69 && internal_format != GL_INTENSITY16 70 && internal_format != GL_R3_G3_B2 71 && internal_format != GL_RED 72 && internal_format != GL_RG 73 && internal_format != GL_RGB 74 && internal_format != GL_RGB4 75 && internal_format != GL_RGB5 76 && internal_format != GL_RGB8 77 && internal_format != GL_RGB10 78 && internal_format != GL_RGB12 79 && internal_format != GL_RGB16 80 && internal_format != GL_RGBA 81 && internal_format != GL_RGBA2 82 && internal_format != GL_RGBA4 83 && internal_format != GL_RGB5_A1 84 && internal_format != GL_RGBA8 85 && internal_format != GL_RGB10_A2 86 && internal_format != GL_RGBA12 87 && internal_format != GL_RGBA16 88 && internal_format != GL_SLUMINANCE 89 && internal_format != GL_SLUMINANCE8 90 && internal_format != GL_SLUMINANCE_ALPHA 91 && internal_format != GL_SLUMINANCE8_ALPHA8 92 && internal_format != GL_SRGB 93 && internal_format != GL_SRGB8 94 && internal_format != GL_SRGB_ALPHA 95 && internal_format != GL_SRGB8_ALPHA8) 96 return Error::from_errno(GL_INVALID_ENUM); 97 98 if (format != GL_NONE 99 && (format < GL_COLOR_INDEX || format > GL_LUMINANCE_ALPHA) 100 && format != GL_BGR 101 && format != GL_BGRA) 102 return Error::from_errno(GL_INVALID_ENUM); 103 104 if (type != GL_NONE 105 && type != GL_BITMAP 106 && (type < GL_BYTE || type > GL_FLOAT) 107 && type != GL_HALF_FLOAT 108 && (type < GL_UNSIGNED_BYTE_3_3_2 || type > GL_UNSIGNED_INT_10_10_10_2) 109 && (type < GL_UNSIGNED_BYTE_2_3_3_REV || type > GL_UNSIGNED_INT_2_10_10_10_REV)) 110 return Error::from_errno(GL_INVALID_ENUM); 111 112 if (type == GL_BITMAP && format != GL_COLOR_INDEX && format != GL_STENCIL_INDEX) 113 return Error::from_errno(GL_INVALID_ENUM); 114 115 if (format != GL_RGB && (type == GL_UNSIGNED_BYTE_3_3_2 || type == GL_UNSIGNED_BYTE_2_3_3_REV || type == GL_UNSIGNED_SHORT_5_6_5 || type == GL_UNSIGNED_SHORT_5_6_5_REV)) 116 return Error::from_errno(GL_INVALID_OPERATION); 117 118 if ((type == GL_UNSIGNED_SHORT_4_4_4_4 119 || type == GL_UNSIGNED_SHORT_4_4_4_4_REV 120 || type == GL_UNSIGNED_SHORT_5_5_5_1 121 || type == GL_UNSIGNED_SHORT_1_5_5_5_REV 122 || type == GL_UNSIGNED_INT_8_8_8_8 123 || type == GL_UNSIGNED_INT_8_8_8_8_REV 124 || type == GL_UNSIGNED_INT_10_10_10_2 125 || type == GL_UNSIGNED_INT_2_10_10_10_REV) 126 && format != GL_RGBA 127 && format != GL_BGRA) 128 return Error::from_errno(GL_INVALID_OPERATION); 129 130 if (internal_format != GL_NONE) { 131 auto const internal_format_is_depth = internal_format == GL_DEPTH_COMPONENT 132 || internal_format == GL_DEPTH_COMPONENT16 133 || internal_format == GL_DEPTH_COMPONENT24 134 || internal_format == GL_DEPTH_COMPONENT32; 135 136 if ((target != GL_TEXTURE_2D && target != GL_PROXY_TEXTURE_2D && internal_format_is_depth) 137 || (format == GL_DEPTH_COMPONENT && !internal_format_is_depth) 138 || (format != GL_DEPTH_COMPONENT && internal_format_is_depth)) 139 return Error::from_errno(GL_INVALID_OPERATION); 140 } 141 142 return get_format_specification(format, type); 143} 144 145GPU::PixelType get_format_specification(GLenum format, GLenum type) 146{ 147 auto get_format = [](GLenum format) -> GPU::PixelFormat { 148 switch (format) { 149 case GL_ALPHA: 150 return GPU::PixelFormat::Alpha; 151 case GL_BGR: 152 return GPU::PixelFormat::BGR; 153 case GL_BGRA: 154 return GPU::PixelFormat::BGRA; 155 case GL_BLUE: 156 return GPU::PixelFormat::Blue; 157 case GL_COLOR_INDEX: 158 return GPU::PixelFormat::ColorIndex; 159 case GL_DEPTH_COMPONENT: 160 return GPU::PixelFormat::DepthComponent; 161 case GL_GREEN: 162 return GPU::PixelFormat::Green; 163 case GL_LUMINANCE: 164 return GPU::PixelFormat::Luminance; 165 case GL_LUMINANCE_ALPHA: 166 return GPU::PixelFormat::LuminanceAlpha; 167 case GL_RED: 168 return GPU::PixelFormat::Red; 169 case GL_RGB: 170 return GPU::PixelFormat::RGB; 171 case GL_RGBA: 172 return GPU::PixelFormat::RGBA; 173 case GL_STENCIL_INDEX: 174 return GPU::PixelFormat::StencilIndex; 175 } 176 VERIFY_NOT_REACHED(); 177 }; 178 auto pixel_format = get_format(format); 179 180 switch (type) { 181 case GL_BITMAP: 182 return { pixel_format, GPU::PixelComponentBits::AllBits, GPU::PixelDataType::Bitmap, GPU::ComponentsOrder::Normal }; 183 case GL_BYTE: 184 return { pixel_format, GPU::PixelComponentBits::AllBits, GPU::PixelDataType::Byte, GPU::ComponentsOrder::Normal }; 185 case GL_FLOAT: 186 return { pixel_format, GPU::PixelComponentBits::AllBits, GPU::PixelDataType::Float, GPU::ComponentsOrder::Normal }; 187 case GL_HALF_FLOAT: 188 return { pixel_format, GPU::PixelComponentBits::AllBits, GPU::PixelDataType::HalfFloat, GPU::ComponentsOrder::Normal }; 189 case GL_INT: 190 return { pixel_format, GPU::PixelComponentBits::AllBits, GPU::PixelDataType::Int, GPU::ComponentsOrder::Normal }; 191 case GL_SHORT: 192 return { pixel_format, GPU::PixelComponentBits::AllBits, GPU::PixelDataType::Short, GPU::ComponentsOrder::Normal }; 193 case GL_UNSIGNED_BYTE: 194 return { pixel_format, GPU::PixelComponentBits::AllBits, GPU::PixelDataType::UnsignedByte, GPU::ComponentsOrder::Normal }; 195 case GL_UNSIGNED_BYTE_2_3_3_REV: 196 return { pixel_format, GPU::PixelComponentBits::B2_3_3, GPU::PixelDataType::UnsignedByte, GPU::ComponentsOrder::Reversed }; 197 case GL_UNSIGNED_BYTE_3_3_2: 198 return { pixel_format, GPU::PixelComponentBits::B3_3_2, GPU::PixelDataType::UnsignedByte, GPU::ComponentsOrder::Normal }; 199 case GL_UNSIGNED_INT: 200 return { pixel_format, GPU::PixelComponentBits::AllBits, GPU::PixelDataType::UnsignedInt, GPU::ComponentsOrder::Normal }; 201 case GL_UNSIGNED_INT_2_10_10_10_REV: 202 return { pixel_format, GPU::PixelComponentBits::B2_10_10_10, GPU::PixelDataType::UnsignedInt, GPU::ComponentsOrder::Reversed }; 203 case GL_UNSIGNED_INT_8_8_8_8: 204 return { pixel_format, GPU::PixelComponentBits::B8_8_8_8, GPU::PixelDataType::UnsignedInt, GPU::ComponentsOrder::Normal }; 205 case GL_UNSIGNED_INT_8_8_8_8_REV: 206 return { pixel_format, GPU::PixelComponentBits::B8_8_8_8, GPU::PixelDataType::UnsignedInt, GPU::ComponentsOrder::Reversed }; 207 case GL_UNSIGNED_INT_10_10_10_2: 208 return { pixel_format, GPU::PixelComponentBits::B10_10_10_2, GPU::PixelDataType::UnsignedInt, GPU::ComponentsOrder::Normal }; 209 case GL_UNSIGNED_SHORT: 210 return { pixel_format, GPU::PixelComponentBits::AllBits, GPU::PixelDataType::UnsignedShort, GPU::ComponentsOrder::Normal }; 211 case GL_UNSIGNED_SHORT_1_5_5_5_REV: 212 return { pixel_format, GPU::PixelComponentBits::B1_5_5_5, GPU::PixelDataType::UnsignedShort, GPU::ComponentsOrder::Reversed }; 213 case GL_UNSIGNED_SHORT_4_4_4_4: 214 return { pixel_format, GPU::PixelComponentBits::B4_4_4_4, GPU::PixelDataType::UnsignedShort, GPU::ComponentsOrder::Normal }; 215 case GL_UNSIGNED_SHORT_4_4_4_4_REV: 216 return { pixel_format, GPU::PixelComponentBits::B4_4_4_4, GPU::PixelDataType::UnsignedShort, GPU::ComponentsOrder::Reversed }; 217 case GL_UNSIGNED_SHORT_5_6_5: 218 return { pixel_format, GPU::PixelComponentBits::B5_6_5, GPU::PixelDataType::UnsignedShort, GPU::ComponentsOrder::Normal }; 219 case GL_UNSIGNED_SHORT_5_6_5_REV: 220 return { pixel_format, GPU::PixelComponentBits::B5_6_5, GPU::PixelDataType::UnsignedShort, GPU::ComponentsOrder::Reversed }; 221 case GL_UNSIGNED_SHORT_5_5_5_1: 222 return { pixel_format, GPU::PixelComponentBits::B5_5_5_1, GPU::PixelDataType::UnsignedShort, GPU::ComponentsOrder::Normal }; 223 } 224 VERIFY_NOT_REACHED(); 225} 226 227GPU::PixelFormat pixel_format_for_internal_format(GLenum internal_format) 228{ 229 // FIXME: add support for all the SRGB formats 230 231 // Numbers 1-4 are supported deprecated values 232 switch (internal_format) { 233 case 1: 234 case GL_ALPHA: 235 case GL_ALPHA4: 236 case GL_ALPHA8: 237 case GL_ALPHA12: 238 case GL_ALPHA16: 239 case GL_COMPRESSED_ALPHA: 240 return GPU::PixelFormat::Alpha; 241 case GL_DEPTH_COMPONENT: 242 case GL_DEPTH_COMPONENT16: 243 case GL_DEPTH_COMPONENT24: 244 case GL_DEPTH_COMPONENT32: 245 return GPU::PixelFormat::DepthComponent; 246 case GL_INTENSITY: 247 case GL_INTENSITY4: 248 case GL_INTENSITY8: 249 case GL_INTENSITY12: 250 case GL_INTENSITY16: 251 case GL_COMPRESSED_INTENSITY: 252 return GPU::PixelFormat::Intensity; 253 case GL_LUMINANCE: 254 case GL_LUMINANCE4: 255 case GL_LUMINANCE8: 256 case GL_LUMINANCE12: 257 case GL_LUMINANCE16: 258 case GL_COMPRESSED_LUMINANCE: 259 return GPU::PixelFormat::Luminance; 260 case 2: 261 case GL_LUMINANCE_ALPHA: 262 case GL_LUMINANCE4_ALPHA4: 263 case GL_LUMINANCE6_ALPHA2: 264 case GL_LUMINANCE8_ALPHA8: 265 case GL_LUMINANCE12_ALPHA4: 266 case GL_LUMINANCE12_ALPHA12: 267 case GL_LUMINANCE16_ALPHA16: 268 return GPU::PixelFormat::LuminanceAlpha; 269 case 3: 270 case GL_RGB: 271 case GL_R3_G3_B2: 272 case GL_RGB4: 273 case GL_RGB5: 274 case GL_RGB8: 275 case GL_RGB10: 276 case GL_RGB12: 277 case GL_RGB16: 278 case GL_COMPRESSED_RGB: 279 return GPU::PixelFormat::RGB; 280 case 4: 281 case GL_RGBA: 282 case GL_RGBA2: 283 case GL_RGBA4: 284 case GL_RGBA8: 285 case GL_RGB10_A2: 286 case GL_RGBA12: 287 case GL_RGBA16: 288 case GL_COMPRESSED_RGBA: 289 return GPU::PixelFormat::RGBA; 290 } 291 VERIFY_NOT_REACHED(); 292} 293 294}