Merge branch 'dev' into Feat/Backend-Direct-Vulkan

This commit is contained in:
BZLZHH
2026-02-21 15:02:59 +08:00
66 changed files with 6120 additions and 6407 deletions
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,59 @@
// MobileGL - MobileGL/MG_Util/BackendLoaders/Vulkan/Loader.cpp
// Copyright (c) 2025-2026 MobileGL-Dev
// Licensed under the GNU Lesser General Public License v3.0:
// https://www.gnu.org/licenses/gpl-3.0.txt
// https://www.gnu.org/licenses/lgpl-3.0.txt
// SPDX-License-Identifier: LGPL-3.0-only
// End of Source File Header
#include "Loader.h"
namespace MobileGL::MG_Util::BackendLoader {
inline Version DecodeApiVersion(uint32_t version) {
return {(Int)VK_VERSION_MAJOR(version), (Int)VK_VERSION_MINOR(version), (Int)VK_VERSION_PATCH(version)};
}
inline std::string DecodeDriverVersion(uint32_t driverVersion) {
std::ostringstream oss;
oss << VK_VERSION_MAJOR(driverVersion) << "." << VK_VERSION_MINOR(driverVersion) << "."
<< VK_VERSION_PATCH(driverVersion);
return oss.str();
}
Bool QueryVulkanCapabilities(MobileGL::MG_External::VulkanCapabilities& caps, VkPhysicalDevice physicalDevice) {
if (!physicalDevice) {
MGLOG_E("Invalid physical device handle");
return false;
}
VkPhysicalDeviceProperties props{};
vkGetPhysicalDeviceProperties(physicalDevice, &props);
if (props.apiVersion < VK_API_VERSION_1_1) {
MGLOG_E("Vulkan API version %u.%u.%u is not supported, requires at least 1.1",
VK_VERSION_MAJOR(props.apiVersion), VK_VERSION_MINOR(props.apiVersion),
VK_VERSION_PATCH(props.apiVersion));
return false;
}
VkPhysicalDeviceProperties2 props2{};
props2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
vkGetPhysicalDeviceProperties2(physicalDevice, &props2);
const VkPhysicalDeviceProperties& p = props2.properties;
caps.VulkanAPIVersion = DecodeApiVersion(p.apiVersion);
caps.DeviceName = p.deviceName;
caps.DriverVersionString = DecodeDriverVersion(p.driverVersion);
caps.UniformBufferOffsetAlignment = static_cast<int>(p.limits.minUniformBufferOffsetAlignment);
return true;
}
void FillInVulkanCapabilities(MobileGL::MG_External::VulkanCapabilities& caps,
VkPhysicalDeviceProperties properties) {
caps.VulkanAPIVersion = DecodeApiVersion(properties.apiVersion);
caps.DeviceName = properties.deviceName;
caps.DriverVersionString = DecodeDriverVersion(properties.driverVersion);
caps.UniformBufferOffsetAlignment = static_cast<int>(properties.limits.minUniformBufferOffsetAlignment);
}
} // namespace MobileGL::MG_Util::BackendLoader
@@ -0,0 +1,26 @@
// MobileGL - MobileGL/MG_Util/BackendLoaders/Vulkan/Loader.h
// Copyright (c) 2025-2026 MobileGL-Dev
// Licensed under the GNU Lesser General Public License v3.0:
// https://www.gnu.org/licenses/gpl-3.0.txt
// https://www.gnu.org/licenses/lgpl-3.0.txt
// SPDX-License-Identifier: LGPL-3.0-only
// End of Source File Header
#pragma once
#include <Includes.h>
namespace MobileGL {
namespace MG_External {
struct VulkanCapabilities {
Version VulkanAPIVersion{1, 0, 0};
String DeviceName;
String DriverVersionString;
Int UniformBufferOffsetAlignment = 256;
};
} // namespace MG_External
namespace MG_Util::BackendLoader {
Bool QueryVulkanCapabilities(MobileGL::MG_External::VulkanCapabilities& caps, VkPhysicalDevice physicalDevice);
void FillInVulkanCapabilities(MobileGL::MG_External::VulkanCapabilities& caps,
VkPhysicalDeviceProperties properties);
} // namespace MG_Util::BackendLoader
} // namespace MobileGL
@@ -12,5 +12,5 @@
namespace MobileGL {
namespace MG_Util {
String ConvertEGLEnumToString(GLenum value);
}
} // namespace MG_Util
} // namespace MobileGL
@@ -12,5 +12,5 @@
namespace MobileGL {
namespace MG_Util {
EShLanguage ConvertGLEnumToEShLanguage(GLenum shaderType);
}
} // namespace MG_Util
} // namespace MobileGL
@@ -12,5 +12,5 @@
namespace MobileGL {
namespace MG_Util {
DataType ConvertGLEnumToDataType(GLenum type);
}
} // namespace MG_Util
} // namespace MobileGL
@@ -30,22 +30,22 @@ namespace MobileGL {
}
switch (attachment) {
case GL_NONE:
return FramebufferAttachmentType::None;
case GL_DEPTH_ATTACHMENT:
return FramebufferAttachmentType::Depth;
case GL_STENCIL_ATTACHMENT:
return FramebufferAttachmentType::Stencil;
case GL_FRONT_LEFT:
return FramebufferAttachmentType::FrontLeft;
case GL_FRONT_RIGHT:
return FramebufferAttachmentType::FrontRight;
case GL_BACK_LEFT:
return FramebufferAttachmentType::BackLeft;
case GL_BACK_RIGHT:
return FramebufferAttachmentType::BackRight;
default:
return FramebufferAttachmentType::Unknown;
case GL_NONE:
return FramebufferAttachmentType::None;
case GL_DEPTH_ATTACHMENT:
return FramebufferAttachmentType::Depth;
case GL_STENCIL_ATTACHMENT:
return FramebufferAttachmentType::Stencil;
case GL_FRONT_LEFT:
return FramebufferAttachmentType::FrontLeft;
case GL_FRONT_RIGHT:
return FramebufferAttachmentType::FrontRight;
case GL_BACK_LEFT:
return FramebufferAttachmentType::BackLeft;
case GL_BACK_RIGHT:
return FramebufferAttachmentType::BackRight;
default:
return FramebufferAttachmentType::Unknown;
}
}
@@ -13,5 +13,5 @@
namespace MobileGL {
namespace MG_Util {
ShaderStage ConvertGLEnumToShaderStage(GLenum type);
}
} // namespace MG_Util
} // namespace MobileGL
@@ -1823,9 +1823,9 @@ namespace MobileGL {
CASE(GL_FOG_SPECULAR_TEXTURE_WIN)
default:
return std::format("0x%x", value);
return std::format("0x{:x}", value);
}
#undef CASE
}
} // namespace MG_Util
} // namespace MobileGL
} // namespace MobileGL
@@ -12,5 +12,5 @@
namespace MobileGL {
namespace MG_Util {
String ConvertGLEnumToString(GLenum value);
}
} // namespace MG_Util
} // namespace MobileGL
@@ -12,5 +12,5 @@
namespace MobileGL {
namespace MG_Util {
GLenum ConvertDataTypeToGLEnum(DataType type);
}
} // namespace MG_Util
} // namespace MobileGL
@@ -13,5 +13,5 @@
namespace MobileGL {
namespace MG_Util {
GLenum ConvertErrorCodeToGLEnum(ErrorCode code);
}
} // namespace MG_Util
} // namespace MobileGL
@@ -29,20 +29,20 @@ namespace MobileGL {
}
switch (type) {
case FramebufferAttachmentType::Depth:
return GL_DEPTH_ATTACHMENT;
case FramebufferAttachmentType::Stencil:
return GL_STENCIL_ATTACHMENT;
case FramebufferAttachmentType::FrontLeft:
return GL_FRONT_LEFT;
case FramebufferAttachmentType::FrontRight:
return GL_FRONT_RIGHT;
case FramebufferAttachmentType::BackLeft:
return GL_BACK_LEFT;
case FramebufferAttachmentType::BackRight:
return GL_BACK_RIGHT;
default:
return GL_NONE;
case FramebufferAttachmentType::Depth:
return GL_DEPTH_ATTACHMENT;
case FramebufferAttachmentType::Stencil:
return GL_STENCIL_ATTACHMENT;
case FramebufferAttachmentType::FrontLeft:
return GL_FRONT_LEFT;
case FramebufferAttachmentType::FrontRight:
return GL_FRONT_RIGHT;
case FramebufferAttachmentType::BackLeft:
return GL_BACK_LEFT;
case FramebufferAttachmentType::BackRight:
return GL_BACK_RIGHT;
default:
return GL_NONE;
}
}
@@ -13,5 +13,5 @@
namespace MobileGL {
namespace MG_Util {
GLenum ConvertShaderStageToGLEnum(ShaderStage stage);
}
} // namespace MG_Util
} // namespace MobileGL
@@ -12,5 +12,5 @@
namespace MobileGL {
namespace MG_Util {
String ConvertDataTypeToString(DataType type);
}
} // namespace MG_Util
} // namespace MobileGL
@@ -12,5 +12,5 @@
namespace MobileGL {
namespace MG_Util {
String ConvertGLExtToString(GLExtension extension);
}
} // namespace MG_Util
} // namespace MobileGL
+1 -1
View File
@@ -12,5 +12,5 @@
namespace MobileGL {
namespace MG_Util {
SizeT GetGLTypeSize(GLenum type);
}
} // namespace MG_Util
} // namespace MobileGL
@@ -72,7 +72,7 @@ namespace MobileGL::MG_Util::PixelStoreProcessor {
// assume 8 bit per channel
// swizzle.size() == channel count
static void ProcessColorSwizzle(void* data, SizeT pixelCount, const Vector<TextureSwizzleParam>& swizzle) {
void ProcessColorSwizzle(void* data, SizeT pixelCount, const Vector<TextureSwizzleParam>& swizzle) {
const auto bpp = swizzle.size();
Uint8* bytes = static_cast<Uint8*>(data);
Uint8 pixelScratch[4];
@@ -172,22 +172,25 @@ namespace MobileGL::MG_Util::PixelStoreProcessor {
return outputPixels;
}
void* ProcessTexturePixelsDataPack(const void* inputPixels, const PixelStoreParameters& params, SizeT pixelSize,
void* ProcessTexturePixelsDataPack(const void* inputPixels, const PixelStoreParameters& params,
TextureInternalFormat srcInternalFormat, TexturePixelDataType srcDataType,
TextureInputFormat dstInputFormat, TexturePixelDataType dstDataType,
IntVec3 dimension, Bool isBitmap, SizeT& outSize) {
if (pixelSize == 0) {
outSize = 0;
return nullptr;
}
const SizeT pixelSize = MG_Util::GetInternalBytesPerPixel(srcInternalFormat, srcDataType);
Int width = dimension.x();
Int height = dimension.y();
Int depth = dimension.z();
const Int outputWidth = (params.RowLength > 0) ? params.RowLength : width;
const SizeT outputRowStride = CalculateRowStride(outputWidth, pixelSize, params.Alignment);
const SizeT inputRowStride = static_cast<SizeT>(width) * pixelSize;
if (pixelSize == 0) {
outSize = 0;
return nullptr;
}
const Int effectiveHeight = (params.ImageHeight > 0) ? params.ImageHeight : height;
// TODO: take care of PixelStoreParameters
const SizeT outputRowStride = width * pixelSize;
const Int effectiveHeight = height;
const SizeT inputRowStride = outputRowStride;
outSize = static_cast<SizeT>(outputRowStride) * static_cast<SizeT>(effectiveHeight) * static_cast<SizeT>(depth);
void* outputPixels = malloc(outSize);
@@ -201,12 +204,22 @@ namespace MobileGL::MG_Util::PixelStoreProcessor {
const Uint8* src = static_cast<const Uint8*>(inputPixels);
Uint8* dst = static_cast<Uint8*>(outputPixels);
dst += static_cast<SizeT>(params.SkipImages) * static_cast<SizeT>(effectiveHeight) * outputRowStride;
dst += static_cast<SizeT>(params.SkipRows) * outputRowStride;
dst += static_cast<SizeT>(params.SkipPixels) * pixelSize;
Vector<Uint8> tempRow(static_cast<SizeT>(width) * pixelSize);
bool needSwizzle = false;
static Vector<TextureSwizzleParam> swizzle;
swizzle = {TextureSwizzleParam::Red, TextureSwizzleParam::Green, TextureSwizzleParam::Blue,
TextureSwizzleParam::Alpha};
if (srcInternalFormat == TextureInternalFormat::RGBA && dstInputFormat == TextureInputFormat::BGRA) {
swizzle = {TextureSwizzleParam::Blue, TextureSwizzleParam::Green, TextureSwizzleParam::Red,
TextureSwizzleParam::Alpha};
needSwizzle = true;
}
if (dstDataType == TexturePixelDataType::UnsignedInt8888) {
std::reverse(swizzle.begin(), swizzle.end());
needSwizzle = true;
}
for (Int z = 0; z < depth; ++z) {
Uint8* layerDst = dst;
const Uint8* layerSrc = src;
@@ -222,6 +235,10 @@ namespace MobileGL::MG_Util::PixelStoreProcessor {
ProcessLSBFirst(tempRow.data(), static_cast<SizeT>(width), 1);
}
if (needSwizzle) {
ProcessColorSwizzle(tempRow.data(), static_cast<SizeT>(width), swizzle);
}
Memcpy(layerDst, tempRow.data(), static_cast<SizeT>(width) * pixelSize);
layerSrc += inputRowStride;
@@ -17,6 +17,9 @@ namespace MobileGL::MG_Util::PixelStoreProcessor {
TextureInternalFormat targetInternalFormat,
TextureInputFormat textureInputFormat, TexturePixelDataType inputDataType,
IntVec3 dimension, Bool isBitmap, SizeT& outSize);
void* ProcessTexturePixelsDataPack(const void* inputPixels, const PixelStoreParameters& params, SizeT pixelSize,
void* ProcessTexturePixelsDataPack(const void* inputPixels, const PixelStoreParameters& params,
TextureInternalFormat srcInternalFormat, TexturePixelDataType srcDataType,
TextureInputFormat dstInputFormat, TexturePixelDataType dstDataType,
IntVec3 dimension, Bool isBitmap, SizeT& outSize);
void ProcessColorSwizzle(void* data, SizeT pixelCount, const Vector<TextureSwizzleParam>& swizzle);
} // namespace MobileGL::MG_Util::PixelStoreProcessor
@@ -17,5 +17,5 @@ namespace MobileGL {
namespace MG_Util::TextureFormatProcessor {
void NormalizePixelFormat(GLenum internalFormat, Flags<PixelFormatNormalizeOptionBit> options,
GLenum* outInternalFormat, GLenum* outFormat, GLenum* outType);
}
} // namespace MG_Util::TextureFormatProcessor
} // namespace MobileGL
+6 -2
View File
@@ -75,6 +75,10 @@ namespace MobileGL {
using E = std::common_type_t<Ts...>;
return std::array<E, sizeof...(Ts)>{{std::forward<Ts>(elems)...}};
}
template <typename T>
inline String ToString(const T& value) {
return std::to_string(value);
}
class RuntimeError : public std::runtime_error {
public:
using std::runtime_error::runtime_error;
@@ -252,7 +256,7 @@ namespace MobileGL {
}
};
struct BackendCap {
struct StaticBackendCapabilityT {
Bool AllowVSOnlyPrograms = false;
};
@@ -268,7 +272,7 @@ namespace MobileGL {
String BackendName;
Optional<String> ExtraVendor;
GLInfo RendererGLInfo;
BackendCap BackendCapability;
StaticBackendCapabilityT StaticBackendCapability;
};
template <typename Bit,