Image.cpp 12 KB

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