diff --git a/CMakeLists.txt b/CMakeLists.txt
index 84e08ce..c2b6fbf 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -34,6 +34,9 @@ include("${FENNEC_SOURCE_DIR}/cmake/platform.cmake")
include("${FENNEC_SOURCE_DIR}/cmake/build.cmake")
include("${FENNEC_SOURCE_DIR}/cmake/compiler.cmake")
+# common defines
+list(APPEND FENNEC_COMPILE_DEFINITIONS "NULL=0")
+
# find dependencies
find_package(Doxygen)
fennec_check_platform()
diff --git a/cmake/opengl.cmake b/cmake/opengl.cmake
index 3d595e4..38e1eb0 100644
--- a/cmake/opengl.cmake
+++ b/cmake/opengl.cmake
@@ -18,13 +18,14 @@
if(FENNEC_GRAPHICS_WANT_EGL)
find_package(OpenGL REQUIRED COMPONENTS EGL)
+ find_package(GLEW REQUIRED)
message(STATUS "EGL Requested")
else()
find_package(OpenGL)
endif()
-if(TARGET OpenGL::GL)
- list(APPEND FENNEC_LINK_LIBRARIES OpenGL::GL)
+if(TARGET OpenGL::GL AND TARGET GLEW::GLEW)
+ list(APPEND FENNEC_LINK_LIBRARIES OpenGL::GL GLEW::GLEW)
list(APPEND FENNEC_COMPILE_DEFINITIONS FENNEC_GRAPHICS_OPENGL=1)
else()
message(FATAL_ERROR "No Suitable OpenGL implementation found.")
@@ -38,9 +39,13 @@ if(FENNEC_GRAPHICS_WANT_EGL)
list(APPEND FENNEC_LINK_LIBRARIES OpenGL::EGL)
list(APPEND FENNEC_COMPILE_DEFINITIONS FENNEC_GRAPHICS_EGL=1)
list(APPEND FENNEC_EXTRA_SOURCES
- include/fennec/platform/opengl/egl/context.h source/platform/opengl/egl/context.cpp
+ include/fennec/renderers/opengl/lib/fwd.h
+ include/fennec/renderers/opengl/lib/enum.h
+ include/fennec/renderers/opengl/lib/buffer.h
include/fennec/renderers/opengl/modern.h
include/fennec/renderers/opengl/fallback.h
+
+ include/fennec/platform/opengl/egl/context.h source/platform/opengl/egl/context.cpp
)
endif()
\ No newline at end of file
diff --git a/include/fennec/math/scalar.h b/include/fennec/math/scalar.h
index 7296e03..d584d77 100644
--- a/include/fennec/math/scalar.h
+++ b/include/fennec/math/scalar.h
@@ -65,9 +65,10 @@
namespace fennec
{
-///
-/// \brief an unsigned integer
-using uint = unsigned int;
+using byte = uint8_t;
+using ubyte = uint8_t;
+using ushort = uint16_t;
+using uint = uint32_t;
}
diff --git a/include/fennec/renderers/opengl/lib/buffer.h b/include/fennec/renderers/opengl/lib/buffer.h
new file mode 100644
index 0000000..15c9c81
--- /dev/null
+++ b/include/fennec/renderers/opengl/lib/buffer.h
@@ -0,0 +1,149 @@
+// =====================================================================================================================
+// fennec, a free and open source game engine
+// Copyright © 2025 Medusa Slockbower
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+// =====================================================================================================================
+
+#ifndef FENNEC_PLATFORM_OPENGL_LIB_H
+#define FENNEC_PLATFORM_OPENGL_LIB_H
+
+#include
+#include
+#include
+
+namespace fennec
+{
+
+namespace gl
+{
+
+template
+class buffer {
+private:
+ static constexpr GLenum get_mutable_traits() {
+ GLenum res;
+
+ // Set READ/DRAW/COPY
+ if constexpr (read) {
+ res = GL_STREAM_READ;
+ } else if constexpr (write) {
+ res = GL_STREAM_DRAW;
+ } else {
+ res = GL_STREAM_COPY;
+ }
+
+ // Set STATIC/DYNAMIC/STREAM
+ if constexpr (client or coherent) {
+ // do nothing
+ } else if constexpr (dynamic or persistent) {
+ res += 6;
+ } else {
+ res += 3;
+ }
+
+ return res;
+ }
+
+public:
+ static constexpr GLenum type = TypeV;
+ static constexpr GLboolean immutable = ImmutableV;
+ static constexpr GLbitfield flags = FlagsV;
+ static constexpr GLboolean read = flags & READ;
+ static constexpr GLboolean write = flags & WRITE;
+ static constexpr GLboolean mapped = read or write;
+ static constexpr GLboolean dynamic = flags & DYNAMIC;
+ static constexpr GLboolean persistent = flags & PERSISTENT;
+ static constexpr GLboolean coherent = flags & COHERENT;
+ static constexpr GLboolean client = flags & CLIENT;
+ static constexpr GLenum usage = get_mutable_traits();
+
+ static_assert(not persistent or persistent == mapped);
+ static_assert(not coherent or coherent == persistent);
+
+ constexpr buffer(void* data, GLsizeiptr size)
+ : _handle()
+ , _size(size) {
+ glGenBuffers(1, &_handle);
+ start();
+ if constexpr(immutable) {
+ glBufferStorage(type, _size, data, flags);
+ } else {
+ glBufferData(type, _size, data, usage);
+ }
+ end();
+ }
+
+ constexpr buffer(buffer&& buff) noexcept
+ : _handle(buff)
+ , _size(buff._size) {
+ }
+
+ constexpr buffer(const buffer&) = delete;
+
+ constexpr buffer& operator=(buffer&& buff) noexcept {
+ glDeleteBuffers(1, &_handle);
+ _handle = buff._handle;
+ _size = buff._size;
+ return *this;
+ }
+
+ constexpr void start() const {
+ glBindBuffer(type, _handle);
+ }
+
+ constexpr void end() const {
+ glBindBuffer(type, NULL);
+ }
+
+ constexpr void clear(GLsizeiptr size, GLintptr offset = 0, const void* data = nullptr, GLenum data_type = BYTE, GLenum format = R, GLenum internal = R8) {
+ size = min(size, _size - offset);
+ if (size <= 0) return;
+ glClearBufferSubData(type, internal, offset, size, format, type, data);
+ }
+
+ template
+ constexpr void copy(const buffer& cpy, GLsizeiptr size, GLintptr write_offset = 0, GLintptr read_offset = 0) {
+ size = fennec::min(size, cpy._size - read_offset);
+ size = fennec::min(size, _size - write_offset);
+ if (size <= 0) return;
+ glBindBuffer(COPY_READ, cpy._handle);
+ glBindBuffer(COPY_WRITE, _handle);
+ glCopyBufferSubData(COPY_READ, COPY_WRITE, read_offset, write_offset, size);
+ glBindBuffer(COPY_READ, NULL);
+ glBindBuffer(COPY_WRITE, NULL);
+ }
+
+ constexpr void write(const void* data, GLsizeiptr size, GLintptr offset = 0) {
+ static_assert(dynamic or persistent and not (client or coherent));
+ size = min(size, _size - offset);
+ glBufferSubData(type, offset, size, data);
+ }
+
+ constexpr void resize()
+
+ constexpr void map() {
+
+ }
+
+private:
+ GLuint _handle;
+ GLsizeiptr _size;
+};
+
+}
+
+}
+
+#endif // FENNEC_PLATFORM_OPENGL_LIB_H
diff --git a/include/fennec/renderers/opengl/lib/enum.h b/include/fennec/renderers/opengl/lib/enum.h
new file mode 100644
index 0000000..b45ed72
--- /dev/null
+++ b/include/fennec/renderers/opengl/lib/enum.h
@@ -0,0 +1,260 @@
+// =====================================================================================================================
+// fennec, a free and open source game engine
+// Copyright © 2025 Medusa Slockbower
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+// =====================================================================================================================
+
+#ifndef FENNEC_RENDERERS_OPENGL_LIB_ENUM_H
+#define FENNEC_RENDERERS_OPENGL_LIB_ENUM_H
+
+#include
+
+namespace fennec
+{
+
+namespace gl
+{
+
+enum buffer_ : GLenum {
+ VERTEX = GL_ARRAY_BUFFER,
+ ELEMENT = GL_ELEMENT_ARRAY_BUFFER,
+ UNIFORM = GL_UNIFORM_BUFFER,
+ SHADER_STORAGE = GL_SHADER_STORAGE_BUFFER,
+ QUERY = GL_QUERY_BUFFER,
+ TEXTURE = GL_TEXTURE_BUFFER,
+ TRANSFORM_FEEDBACK = GL_TRANSFORM_FEEDBACK_BUFFER,
+ ATOMIC_COUNTER = GL_ATOMIC_COUNTER_BUFFER,
+ PARAMETER = GL_PARAMETER_BUFFER,
+ INDIRECT_DRAW = GL_DRAW_INDIRECT_BUFFER, INDIRECT_DISPATCH = GL_DISPATCH_INDIRECT_BUFFER,
+ COPY_READ = GL_COPY_READ_BUFFER, COPY_WRITE = GL_COPY_WRITE_BUFFER,
+ PIXEL_PACK = GL_PIXEL_PACK_BUFFER, PIXEL_UNPACK = GL_PIXEL_UNPACK_BUFFER,
+};
+
+enum buffer_flag_ : GLbitfield {
+ NONE = 0,
+ READ = GL_MAP_READ_BIT,
+ WRITE = GL_MAP_WRITE_BIT,
+ DYNAMIC = GL_DYNAMIC_STORAGE_BIT,
+ PERSISTENT = GL_MAP_PERSISTENT_BIT,
+ COHERENT = GL_MAP_COHERENT_BIT,
+ CLIENT = GL_CLIENT_STORAGE_BIT,
+};
+
+enum type_ : GLenum {
+ BOOL = GL_BOOL,
+ BVEC2 = GL_BOOL_VEC2,
+ BVEC3 = GL_BOOL_VEC3,
+ BVEC4 = GL_BOOL_VEC4,
+ BYTE = GL_BYTE,
+ SHORT = GL_SHORT,
+ INT = GL_INT,
+ IVEC2 = GL_INT_VEC2,
+ IVEC3 = GL_INT_VEC3,
+ IVEC4 = GL_INT_VEC4,
+ UBYTE = GL_UNSIGNED_BYTE,
+ USHORT = GL_UNSIGNED_SHORT,
+ UINT = GL_UNSIGNED_INT,
+ UVEC2 = GL_UNSIGNED_INT_VEC2,
+ UVEC3 = GL_UNSIGNED_INT_VEC3,
+ UVEC4 = GL_UNSIGNED_INT_VEC4,
+
+ HALF = GL_HALF_FLOAT,
+ FLOAT = GL_FLOAT,
+ VEC2 = GL_FLOAT_VEC2,
+ VEC3 = GL_FLOAT_VEC3,
+ VEC4 = GL_FLOAT_VEC4,
+ DOUBLE = GL_DOUBLE,
+ DVEC2 = GL_DOUBLE_VEC2,
+ DVEC3 = GL_DOUBLE_VEC3,
+ DVEC4 = GL_DOUBLE_VEC4,
+
+ UBYTE332 = GL_UNSIGNED_BYTE_3_3_2,
+ UBYTE233R = GL_UNSIGNED_BYTE_2_3_3_REV,
+ USHORT565 = GL_UNSIGNED_SHORT_5_6_5,
+ USHORT565R = GL_UNSIGNED_SHORT_5_6_5_REV,
+ USHORT4444 = GL_UNSIGNED_SHORT_4_4_4_4,
+ USHORT4444R = GL_UNSIGNED_SHORT_4_4_4_4_REV,
+ USHORT5551 = GL_UNSIGNED_SHORT_5_5_5_1,
+ USHORT1555R = GL_UNSIGNED_SHORT_1_5_5_5_REV,
+ UINT8888 = GL_UNSIGNED_INT_8_8_8_8,
+ UINT8888R = GL_UNSIGNED_INT_8_8_8_8_REV,
+ UINTAAA2 = GL_UNSIGNED_INT_10_10_10_2,
+ UINT2AAAR = GL_UNSIGNED_INT_2_10_10_10_REV,
+ UINT24_8 = GL_UNSIGNED_INT_24_8,
+
+ UINTABBFR = GL_UNSIGNED_INT_10F_11F_11F_REV,
+ UINT5999R = GL_UNSIGNED_INT_5_9_9_9_REV,
+ FLOAT32UINT24 = GL_FLOAT_32_UNSIGNED_INT_24_8_REV,
+
+ SAMPLER_1D = GL_SAMPLER_1D,
+ SAMPLER_1D_V = GL_SAMPLER_1D_ARRAY,
+ SHADOW_SAMPLER_1D = GL_SAMPLER_1D_SHADOW,
+ SHADOW_SAMPLER_1D_V = GL_SAMPLER_1D_ARRAY_SHADOW,
+
+ SAMPLER_2D = GL_SAMPLER_2D,
+ SAMPLER_2D_V = GL_SAMPLER_2D_ARRAY,
+ SAMPLER_RECT_2D = GL_SAMPLER_2D_RECT,
+ SAMPLER_2D_MS = GL_SAMPLER_2D_MULTISAMPLE,
+ SAMPLER_2D_MS_V = GL_SAMPLER_2D_MULTISAMPLE_ARRAY,
+ SHADOW_SAMPLER_2D = GL_SAMPLER_2D_SHADOW,
+ SHADOW_SAMPLER_2D_V = GL_SAMPLER_2D_ARRAY_SHADOW,
+ SHADOW_SAMPLER_RECT_2D = GL_SAMPLER_2D_RECT_SHADOW,
+ SAMPLER_CUBEMAP = GL_SAMPLER_CUBE,
+ SHADOW_SAMPLER_CUBEMAP = GL_SAMPLER_CUBE_SHADOW,
+ SAMPLER_3D = GL_SAMPLER_3D,
+ SAMPLER_BUFFER = GL_SAMPLER_BUFFER,
+
+ ISAMPLER_1D = GL_INT_SAMPLER_1D,
+ ISAMPLER_1D_V = GL_INT_SAMPLER_1D_ARRAY,
+ ISAMPLER_2D = GL_INT_SAMPLER_2D,
+ ISAMPLER_2D_V = GL_INT_SAMPLER_2D_ARRAY,
+ ISAMPLER_RECT_2D = GL_INT_SAMPLER_2D_RECT,
+ ISAMPLER_2D_MS = GL_INT_SAMPLER_2D_MULTISAMPLE,
+ ISAMPLER_2D_MS_V = GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY,
+ ISAMPLER_CUBEMAP = GL_INT_SAMPLER_CUBE,
+ ISAMPLER_3D = GL_INT_SAMPLER_3D,
+ ISAMPLER_BUFFER = GL_INT_SAMPLER_BUFFER,
+
+ USAMPLER_1D = GL_INT_SAMPLER_1D,
+ USAMPLER_1D_V = GL_INT_SAMPLER_1D_ARRAY,
+ USAMPLER_2D = GL_INT_SAMPLER_2D,
+ USAMPLER_2D_V = GL_INT_SAMPLER_2D_ARRAY,
+ USAMPLER_RECT_2D = GL_INT_SAMPLER_2D_RECT,
+ USAMPLER_2D_MS = GL_INT_SAMPLER_2D_MULTISAMPLE,
+ USAMPLER_2D_MS_V = GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY,
+ USAMPLER_CUBEMAP = GL_INT_SAMPLER_CUBE,
+ USAMPLER_3D = GL_INT_SAMPLER_3D,
+ USAMPLER_BUFFER = GL_INT_SAMPLER_BUFFER,
+
+ IMAGE_1D = GL_IMAGE_1D,
+ IMAGE_1D_V = GL_IMAGE_1D_ARRAY,
+ IMAGE_2D = GL_IMAGE_2D,
+ IMAGE_2D_V = GL_IMAGE_2D_ARRAY,
+ IMAGE_RECT_2D = GL_IMAGE_2D_RECT,
+ IMAGE_2D_MS = GL_IMAGE_2D_MULTISAMPLE,
+ IMAGE_2D_MS_V = GL_IMAGE_2D_MULTISAMPLE_ARRAY,
+ IMAGE_CUBEMAP = GL_IMAGE_CUBE,
+ IMAGE_3D = GL_IMAGE_3D,
+ IMAGE_BUFFER = GL_IMAGE_BUFFER,
+
+ IIMAGE_1D = GL_INT_IMAGE_1D,
+ IIMAGE_1D_V = GL_INT_IMAGE_1D_ARRAY,
+ IIMAGE_2D = GL_INT_IMAGE_2D,
+ IIMAGE_2D_V = GL_INT_IMAGE_2D_ARRAY,
+ IIMAGE_RECT_2D = GL_INT_IMAGE_2D_RECT,
+ IIMAGE_2D_MS = GL_INT_IMAGE_2D_MULTISAMPLE,
+ IIMAGE_2D_MS_V = GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY,
+ IIMAGE_CUBEMAP = GL_INT_IMAGE_CUBE,
+ IIMAGE_3D = GL_INT_IMAGE_3D,
+ IIMAGE_BUFFER = GL_INT_IMAGE_BUFFER,
+
+ UIMAGE_1D = GL_UNSIGNED_INT_IMAGE_1D,
+ UIMAGE_1D_V = GL_UNSIGNED_INT_IMAGE_1D_ARRAY,
+ UIMAGE_2D = GL_UNSIGNED_INT_IMAGE_2D,
+ UIMAGE_2D_V = GL_UNSIGNED_INT_IMAGE_2D_ARRAY,
+ UIMAGE_RECT_2D = GL_UNSIGNED_INT_IMAGE_2D_RECT,
+ UIMAGE_2D_MS = GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE,
+ UIMAGE_2D_MS_V = GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY,
+ UIMAGE_CUBEMAP = GL_UNSIGNED_INT_IMAGE_CUBE,
+ UIMAGE_3D = GL_UNSIGNED_INT_IMAGE_3D,
+ UIMAGE_BUFFER = GL_UNSIGNED_INT_IMAGE_BUFFER,
+
+ AtomicCounter = GL_UNSIGNED_INT_ATOMIC_COUNTER,
+};
+
+enum component_ : GLenum {
+ ZERO = GL_ZERO,
+ ONE = GL_ONE,
+ R = GL_RED,
+ G = GL_GREEN,
+ B = GL_BLUE,
+ A = GL_ALPHA,
+ RGB = GL_RGB,
+ BGR = GL_BGR,
+ RGBA = GL_RGBA,
+ BGRA = GL_BGRA,
+ RI = GL_RED_INTEGER,
+ GI = GL_GREEN_INTEGER,
+ BI = GL_BLUE_INTEGER,
+ AI = GL_ALPHA_INTEGER,
+ RGBI = GL_RGB_INTEGER,
+ BGRI = GL_BGR_INTEGER,
+ RGBAI = GL_RGBA_INTEGER,
+ BGRAI = GL_BGRA_INTEGER,
+ STENCIL = GL_STENCIL_INDEX,
+ DEPTH = GL_DEPTH_COMPONENT,
+ DEPTH_STENCIL = GL_DEPTH_STENCIL,
+};
+
+enum format_ : GLenum {
+ R8 = GL_R8,
+ R8_SNORM = GL_R8_SNORM,
+ R16 = GL_R16,
+ R16_SNORM = GL_R16_SNORM,
+
+ RG8 = GL_RG8,
+ RG8_SNORM = GL_RG8_SNORM,
+ RG16 = GL_RG16,
+ RG16_SNORM = GL_RG16_SNORM,
+
+ RGB332 = GL_R3_G3_B2,
+ RGB4 = GL_RGB4,
+ RGB5 = GL_RGB5,
+ RGB8 = GL_RGB8,
+ RGB8_SNORM = GL_RGB8_SNORM,
+ RGB10 = GL_RGB10,
+ RGB12 = GL_RGB12,
+ RGB16 = GL_RGB16,
+ RGB16_SNORM = GL_RGB16_SNORM,
+
+ RGBA2 = GL_RGBA2,
+ RGBA4 = GL_RGBA4,
+ RGB5_A1 = GL_RGB5_A1,
+ RGBA8 = GL_RGBA8,
+ RGBA8_SNORM = GL_RGBA8_SNORM,
+ RGB10_A2 = GL_RGB10_A2,
+ RGB10_A2UI = GL_RGB10_A2UI,
+ RGBA12 = GL_RGBA12,
+ RGBA16 = GL_RGBA16,
+
+ SRGB8 = GL_SRGB8,
+ SRGBA8 = GL_SRGB8_ALPHA8,
+
+ R16F = GL_R16F,
+ RG16F = GL_RG16F,
+ RGB16F = GL_RGB16F,
+ RGBA16F = GL_RGBA16F,
+
+ R32F = GL_R32F,
+ RG32F = GL_RG32F,
+ RGB32F = GL_RGB32F,
+ RGBA32F = GL_RGBA32F,
+
+ R16I = GL_R16I,
+ RG16I = GL_RG16I,
+ RGB16I = GL_RGB16I,
+ RGBA16I = GL_RGBA16I,
+
+ R32UI = GL_R32UI,
+ RG32UI = GL_RG32UI,
+ RGB32UI = GL_RGB32UI,
+ RGBA32UI = GL_RGBA32UI,
+};
+
+}
+
+}
+
+#endif // FENNEC_RENDERERS_OPENGL_LIB_ENUM_H
diff --git a/include/fennec/renderers/opengl/lib/fwd.h b/include/fennec/renderers/opengl/lib/fwd.h
new file mode 100644
index 0000000..f162301
--- /dev/null
+++ b/include/fennec/renderers/opengl/lib/fwd.h
@@ -0,0 +1,25 @@
+// =====================================================================================================================
+// fennec, a free and open source game engine
+// Copyright © 2025 Medusa Slockbower
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+// =====================================================================================================================
+
+#ifndef FENNEC_RENDERERS_OPENGL_LIB_FWD_H
+#define FENNEC_RENDERERS_OPENGL_LIB_FWD_H
+
+#include
+#include
+
+#endif // FENNEC_RENDERERS_OPENGL_LIB_FWD_H
diff --git a/include/fennec/renderers/opengl/modern.h b/include/fennec/renderers/opengl/modern.h
index e183c35..9d23899 100644
--- a/include/fennec/renderers/opengl/modern.h
+++ b/include/fennec/renderers/opengl/modern.h
@@ -23,12 +23,14 @@
*
* Requires the following:
* OpenGL 4.6 OR
- * - ARB_shader_draw_parameters
- * - ARB_multi_draw_indirect
- * - EXT_texture_array
+ * - ARB_buffer_storage
* - ARB_compute_shader
+ * - ARB_multi_draw_indirect
+ * - ARB_shader_draw_parameters
* - ARB_shader_image_load_store
* - ARB_texture_cube_map_array
+ * - ARB_texture_storage
+ * - EXT_texture_array
*
* This will support >91.31% of devices on Steam, including all Desktop GPUs and iGPUs since 2012
*/