mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-08 04:08:32 +09:00
[Fix] (MG_Backend/DirectVulkan): make glmark2 work on Magma
This commit is contained in:
@@ -110,10 +110,32 @@
|
||||
#define VK_USE_PLATFORM_WIN32_KHR
|
||||
#elif defined(__APPLE__)
|
||||
#define VK_USE_PLATFORM_METAL_EXT
|
||||
#elif defined(__linux__)
|
||||
#define VK_USE_PLATFORM_XLIB_KHR
|
||||
typedef struct _XDisplay Display;
|
||||
typedef unsigned long XID;
|
||||
typedef XID Window;
|
||||
typedef unsigned long VisualID;
|
||||
#else
|
||||
#warning "VK_USE_PLATFORM_*_KHR not defined for this platform!"
|
||||
#endif
|
||||
#if defined(VK_USE_PLATFORM_XLIB_KHR)
|
||||
#pragma push_macro("Bool")
|
||||
#pragma push_macro("None")
|
||||
#pragma push_macro("Always")
|
||||
#pragma push_macro("Status")
|
||||
#pragma push_macro("LSBFirst")
|
||||
#pragma push_macro("DestroyAll")
|
||||
#endif
|
||||
#include <vulkan/vulkan.h>
|
||||
#if defined(VK_USE_PLATFORM_XLIB_KHR)
|
||||
#pragma pop_macro("DestroyAll")
|
||||
#pragma pop_macro("LSBFirst")
|
||||
#pragma pop_macro("Status")
|
||||
#pragma pop_macro("Always")
|
||||
#pragma pop_macro("None")
|
||||
#pragma pop_macro("Bool")
|
||||
#endif
|
||||
|
||||
#ifdef TRACY_ENABLE
|
||||
#include <tracy/Tracy.hpp>
|
||||
|
||||
@@ -164,6 +164,14 @@ namespace MobileGL::MG_Backend {
|
||||
return true;
|
||||
}
|
||||
|
||||
void BackendObject::ReleaseEGLResources() {
|
||||
const std::lock_guard<std::recursive_mutex> lock(m_eglStateMutex);
|
||||
ResetEGLRuntimeState();
|
||||
m_eglDisplay = EGL_NO_DISPLAY;
|
||||
m_eglDisplayInitialized = false;
|
||||
m_windowHandle = {};
|
||||
}
|
||||
|
||||
void BackendObject::SetWindowHandle(const WindowHandle& handle) {
|
||||
const std::lock_guard<std::recursive_mutex> lock(m_eglStateMutex);
|
||||
m_windowHandle = handle;
|
||||
|
||||
@@ -118,6 +118,7 @@ namespace MobileGL {
|
||||
virtual Bool CreateEGLPbufferSurface(EGLint width, EGLint height);
|
||||
virtual Bool MakeEGLCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx);
|
||||
virtual Bool SwapEGLBuffers(EGLDisplay dpy, EGLSurface draw);
|
||||
virtual void ReleaseEGLResources();
|
||||
|
||||
void SetWindowHandle(const WindowHandle& handle);
|
||||
|
||||
|
||||
@@ -113,6 +113,12 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
return BackendObject::SwapEGLBuffers(dpy, draw);
|
||||
}
|
||||
|
||||
void BackendObject_DirectGLES::ReleaseEGLResources() {
|
||||
const std::lock_guard<std::recursive_mutex> lock(m_eglStateMutex);
|
||||
DestroyEGLContext();
|
||||
BackendObject::ReleaseEGLResources();
|
||||
}
|
||||
|
||||
const RendererInfo& BackendObject_DirectGLES::GetRendererInfo() const {
|
||||
static RendererInfo RendererInfo = {
|
||||
.RendererName = "Espryt", // Renderer Name
|
||||
|
||||
@@ -23,6 +23,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
Bool CreateEGLWindowSurface(const WindowHandle& handle) override;
|
||||
Bool MakeEGLCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx) override;
|
||||
Bool SwapEGLBuffers(EGLDisplay dpy, EGLSurface draw) override;
|
||||
void ReleaseEGLResources() override;
|
||||
|
||||
const RendererInfo& GetRendererInfo() const override;
|
||||
String GetBackendAPIVersionString() const override;
|
||||
|
||||
@@ -1943,7 +1943,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
}
|
||||
|
||||
using XOpenDisplayFn = Display* (*)(const char*);
|
||||
using XGetWindowAttributesFn = Status (*)(Display*, Window, XWindowAttributes*);
|
||||
using XGetWindowAttributesFn = int (*)(Display*, Window, XWindowAttributes*);
|
||||
using XVisualIDFromVisualFn = unsigned long (*)(Visual*);
|
||||
using XCloseDisplayFn = int (*)(Display*);
|
||||
|
||||
|
||||
@@ -66,8 +66,8 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
MGLOG_E("DirectVulkan backend not initialized");
|
||||
return false;
|
||||
}
|
||||
if (handle.Backend != WindowBackend::Android || !handle.Handle) {
|
||||
MGLOG_E("DirectVulkan backend only supports Android native windows");
|
||||
if (!handle.Handle || (handle.Backend != WindowBackend::Android && handle.Backend != WindowBackend::X11)) {
|
||||
MGLOG_E("DirectVulkan backend only supports Android and X11 native windows");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -106,6 +106,12 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
return BackendObject::SwapEGLBuffers(dpy, draw);
|
||||
}
|
||||
|
||||
void BackendObject_DirectVulkan::ReleaseEGLResources() {
|
||||
const std::lock_guard<std::recursive_mutex> lock(m_eglStateMutex);
|
||||
pVulkanRenderer.reset();
|
||||
BackendObject::ReleaseEGLResources();
|
||||
}
|
||||
|
||||
const RendererInfo& BackendObject_DirectVulkan::GetRendererInfo() const {
|
||||
static RendererInfo RendererInfo = {
|
||||
.RendererName = "Magma", // Renderer Name
|
||||
@@ -118,7 +124,8 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
.Extensions = {V_OpenGL30, V_OpenGL31, V_OpenGL32, // OpenGL Extensions
|
||||
V_OpenGL33, E_GL_ARB_draw_buffers_blend, E_GL_ARB_compute_shader,
|
||||
E_GL_ARB_shader_storage_buffer_object, E_GL_ARB_shader_image_load_store,
|
||||
E_GL_ARB_program_interface_query},
|
||||
E_GL_ARB_program_interface_query, E_GL_ARB_framebuffer_object,
|
||||
E_GL_EXT_framebuffer_object, E_GL_ARB_depth_texture},
|
||||
.IsCompatibilityProfile = false // Is Compatibility Profile
|
||||
},
|
||||
.StaticBackendCapability = {.AllowVSOnlyPrograms = false} // Backend Capability
|
||||
|
||||
@@ -23,6 +23,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
Bool CreateEGLWindowSurface(const WindowHandle& handle) override;
|
||||
Bool MakeEGLCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx) override;
|
||||
Bool SwapEGLBuffers(EGLDisplay dpy, EGLSurface draw) override;
|
||||
void ReleaseEGLResources() override;
|
||||
|
||||
const RendererInfo& GetRendererInfo() const override;
|
||||
String GetBackendAPIVersionString() const override;
|
||||
|
||||
@@ -52,10 +52,8 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
}
|
||||
|
||||
VertexInputStateBuilder builder;
|
||||
UnorderedMap<SizeT, Uint32> bindingByBufferKey;
|
||||
UnorderedMap<SizeT, Uint32> strideByBufferKey;
|
||||
UnorderedMap<SizeT, VkVertexInputRate> inputRateByBufferKey;
|
||||
Vector<SizeT> bindingBufferKeys;
|
||||
Vector<SizeT> bindingBaseOffsets;
|
||||
|
||||
for (Uint32 location = 0; location < MG_State::GLState::VertexArrayObject::MAX_VERTEX_ATTRIBS; ++location) {
|
||||
const auto& attr = vao.GetAttribute(location);
|
||||
@@ -84,29 +82,11 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
(attr.Divisor == 0) ? VK_VERTEX_INPUT_RATE_VERTEX : VK_VERTEX_INPUT_RATE_INSTANCE;
|
||||
|
||||
const SizeT bufferKey = reinterpret_cast<SizeT>(attr.Buffer.get());
|
||||
Uint32 binding = 0;
|
||||
auto itBinding = bindingByBufferKey.find(bufferKey);
|
||||
if (itBinding == bindingByBufferKey.end()) {
|
||||
binding = static_cast<Uint32>(bindingByBufferKey.size());
|
||||
bindingByBufferKey.emplace(bufferKey, binding);
|
||||
strideByBufferKey.emplace(bufferKey, stride);
|
||||
inputRateByBufferKey.emplace(bufferKey, inputRate);
|
||||
bindingBufferKeys.push_back(bufferKey);
|
||||
builder.AddBinding(binding, stride, inputRate);
|
||||
} else {
|
||||
binding = itBinding->second;
|
||||
if (strideByBufferKey[bufferKey] != stride) {
|
||||
MGLOG_D("Skipping vertex attribute at location %u: stride mismatch (%u vs %u) on same buffer",
|
||||
location, stride, strideByBufferKey[bufferKey]);
|
||||
continue;
|
||||
}
|
||||
if (inputRateByBufferKey[bufferKey] != inputRate) {
|
||||
MGLOG_D("Skipping vertex attribute at location %u: input-rate mismatch on same buffer", location);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
builder.AddAttribute(location, binding, vkFormat, static_cast<Uint32>(attr.Offset));
|
||||
const Uint32 binding = static_cast<Uint32>(bindingBufferKeys.size());
|
||||
bindingBufferKeys.push_back(bufferKey);
|
||||
bindingBaseOffsets.push_back(attr.Offset);
|
||||
builder.AddBinding(binding, stride, inputRate);
|
||||
builder.AddAttribute(location, binding, vkFormat, 0);
|
||||
}
|
||||
|
||||
const auto& state = builder.Build();
|
||||
@@ -116,6 +96,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
entry.bindings = builder.GetBindings();
|
||||
entry.attributes = builder.GetAttributes();
|
||||
entry.bindingBufferKeys = std::move(bindingBufferKeys);
|
||||
entry.bindingBaseOffsets = std::move(bindingBaseOffsets);
|
||||
entry.state = state;
|
||||
entry.state.pVertexBindingDescriptions = entry.bindings.empty() ? nullptr : entry.bindings.data();
|
||||
entry.state.pVertexAttributeDescriptions = entry.attributes.empty() ? nullptr : entry.attributes.data();
|
||||
|
||||
@@ -24,6 +24,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
Vector<VkVertexInputBindingDescription> bindings;
|
||||
Vector<VkVertexInputAttributeDescription> attributes;
|
||||
Vector<SizeT> bindingBufferKeys;
|
||||
Vector<SizeT> bindingBaseOffsets;
|
||||
VkPipelineVertexInputStateCreateInfo state{
|
||||
VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO
|
||||
};
|
||||
|
||||
@@ -1331,6 +1331,22 @@ void main() {
|
||||
m_surface = VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
#if defined(VK_USE_PLATFORM_XLIB_KHR)
|
||||
if (m_platformDisplay != nullptr) {
|
||||
using XCloseDisplayFn = int (*)(Display*);
|
||||
auto* closeDisplay = reinterpret_cast<XCloseDisplayFn>(m_platformCloseDisplay);
|
||||
if (closeDisplay) {
|
||||
closeDisplay(static_cast<Display*>(m_platformDisplay));
|
||||
}
|
||||
m_platformDisplay = nullptr;
|
||||
}
|
||||
m_platformCloseDisplay = nullptr;
|
||||
if (m_platformLibrary != nullptr) {
|
||||
dlclose(m_platformLibrary);
|
||||
m_platformLibrary = nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (m_debugMessenger != VK_NULL_HANDLE) {
|
||||
DestroyDebugMessenger();
|
||||
m_debugMessenger = VK_NULL_HANDLE;
|
||||
@@ -1413,7 +1429,12 @@ void main() {
|
||||
}
|
||||
}
|
||||
vkBuffers[binding] = slice.buffer;
|
||||
vkOffsets[binding] = slice.offset;
|
||||
const SizeT baseOffset =
|
||||
binding < vertexInputState.bindingBaseOffsets.size() ? vertexInputState.bindingBaseOffsets[binding] : 0;
|
||||
MOBILEGL_ASSERT(baseOffset <= sourceSize,
|
||||
"UploadAndBindVertexStreams skipped: binding %zu base offset %zu exceeds buffer size %zu",
|
||||
binding, baseOffset, sourceSize);
|
||||
vkOffsets[binding] = slice.offset + static_cast<VkDeviceSize>(baseOffset);
|
||||
}
|
||||
|
||||
SizeT syntheticBinding = vertexInputState.bindings.size();
|
||||
@@ -3515,8 +3536,15 @@ void main() {
|
||||
resource = m_textureManager->SyncTextureAndGetDescriptor(*texture);
|
||||
MOBILEGL_ASSERT(resource != nullptr && resource->image != VK_NULL_HANDLE,
|
||||
"GenerateMipmap failed to resync the backend texture after allocating mip storage.");
|
||||
MOBILEGL_ASSERT(resource->layout != VK_IMAGE_LAYOUT_UNDEFINED,
|
||||
"GenerateMipmap requires initialized base-level image data.");
|
||||
if (resource->layout == VK_IMAGE_LAYOUT_UNDEFINED) {
|
||||
const VkImageLayout finalLayout = ResolveGenerateMipmapFinalLayout(resource->aspect);
|
||||
Bool transitioned = VkTextureManager::TransitionImageLayout(
|
||||
frame.commandBuffer, resource->image, resource->layout, finalLayout,
|
||||
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
|
||||
0, VK_ACCESS_SHADER_READ_BIT, resource->aspect, 0, resource->mipLevels, resource->arrayLayers);
|
||||
MOBILEGL_ASSERT(transitioned, "GenerateMipmap: failed to transition uninitialized mip chain");
|
||||
return;
|
||||
}
|
||||
|
||||
const IntVec3 storageBaseTexelSize = {
|
||||
static_cast<Int>(resource->extent.width),
|
||||
@@ -3801,6 +3829,8 @@ void main() {
|
||||
VK_KHR_WIN32_SURFACE_EXTENSION_NAME
|
||||
#elif defined VK_USE_PLATFORM_METAL_EXT
|
||||
VK_EXT_METAL_SURFACE_EXTENSION_NAME
|
||||
#elif defined VK_USE_PLATFORM_XLIB_KHR
|
||||
VK_KHR_XLIB_SURFACE_EXTENSION_NAME
|
||||
#else
|
||||
#warning "VulkanContext::CreateInstance: VK_KHR_*_surface extension not defined on this platform"
|
||||
#endif
|
||||
@@ -4195,6 +4225,31 @@ void main() {
|
||||
VkMetalSurfaceCreateInfoEXT sci{VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT};
|
||||
sci.pLayer = reinterpret_cast<const void*>(m_window);
|
||||
VK_VERIFY(vkCreateMetalSurfaceEXT(m_instance, &sci, nullptr, &m_surface), "vkCreateMetalSurfaceEXT failed");
|
||||
#elif defined VK_USE_PLATFORM_XLIB_KHR
|
||||
MOBILEGL_ASSERT(m_window, "X11 Window is null");
|
||||
|
||||
void* x11Lib = dlopen("libX11.so.6", RTLD_LOCAL | RTLD_NOW);
|
||||
if (!x11Lib) {
|
||||
x11Lib = dlopen("libX11.so", RTLD_LOCAL | RTLD_NOW);
|
||||
}
|
||||
MOBILEGL_ASSERT(x11Lib != nullptr, "Failed to open libX11 while creating Vulkan Xlib surface");
|
||||
using XOpenDisplayFn = Display* (*)(const char*);
|
||||
using XCloseDisplayFn = int (*)(Display*);
|
||||
auto* xOpenDisplay = reinterpret_cast<XOpenDisplayFn>(dlsym(x11Lib, "XOpenDisplay"));
|
||||
auto* xCloseDisplay = reinterpret_cast<XCloseDisplayFn>(dlsym(x11Lib, "XCloseDisplay"));
|
||||
MOBILEGL_ASSERT(xOpenDisplay != nullptr && xCloseDisplay != nullptr,
|
||||
"Failed to resolve XOpenDisplay/XCloseDisplay while creating Vulkan Xlib surface");
|
||||
|
||||
auto* display = xOpenDisplay(std::getenv("DISPLAY"));
|
||||
MOBILEGL_ASSERT(display != nullptr, "XOpenDisplay failed while creating Vulkan Xlib surface");
|
||||
m_platformDisplay = display;
|
||||
m_platformLibrary = x11Lib;
|
||||
m_platformCloseDisplay = reinterpret_cast<void*>(xCloseDisplay);
|
||||
|
||||
VkXlibSurfaceCreateInfoKHR sci{VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR};
|
||||
sci.dpy = display;
|
||||
sci.window = static_cast<Window>(m_window);
|
||||
VK_VERIFY(vkCreateXlibSurfaceKHR(m_instance, &sci, nullptr, &m_surface), "vkCreateXlibSurfaceKHR failed");
|
||||
#else
|
||||
// #warning "VulkanRenderer::Initialize called on a platform which is not supported yet"
|
||||
MGLOG_W("VulkanRenderer::Initialize called on a platform which is not supported yet"); // TODO: support more
|
||||
|
||||
@@ -174,6 +174,9 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
void QueueClearBufferPayload(GLenum buffer, GLint drawbuffer, const ClearAttachmentPayload& clearPayload);
|
||||
|
||||
NativeWindowType m_window = 0;
|
||||
void* m_platformDisplay = nullptr;
|
||||
void* m_platformLibrary = nullptr;
|
||||
void* m_platformCloseDisplay = nullptr;
|
||||
VulkanRendererConfig m_config;
|
||||
|
||||
// Vulkan objects
|
||||
|
||||
@@ -244,7 +244,13 @@ namespace MobileGL::MG_Impl::EGLImpl {
|
||||
if (!state) {
|
||||
return EGL_FALSE;
|
||||
}
|
||||
return state->TerminateDisplay(dpy) ? EGL_TRUE : EGL_FALSE;
|
||||
if (!state->TerminateDisplay(dpy)) {
|
||||
return EGL_FALSE;
|
||||
}
|
||||
if (auto* backendObject = MG_Backend::pActiveBackendObject.get()) {
|
||||
backendObject->ReleaseEGLResources();
|
||||
}
|
||||
return EGL_TRUE;
|
||||
}
|
||||
|
||||
EGLBoolean ReleaseThread() {
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
|
||||
namespace MobileGL::MG_Impl::GLImpl {
|
||||
static SharedPtr<MG_State::GLState::ITextureObject> nullTextureObject;
|
||||
static UnorderedMap<Uint, Bool> g_autoGenerateMipmapByTextureId;
|
||||
|
||||
const SharedPtr<MG_State::GLState::ITextureObject>& GetTextureObjectByTarget(
|
||||
TextureUploadTarget textureUploadTarget, TextureTarget textureTarget) {
|
||||
@@ -50,6 +51,18 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
MG_Backend::gBackendFunctionsTable.GL.GenerateMipmap(target);
|
||||
}
|
||||
|
||||
void MaybeAutoGenerateMipmap(GLenum target, const SharedPtr<MG_State::GLState::ITextureObject>& textureObject,
|
||||
Bool isProxy, GLint level) {
|
||||
if (isProxy || level != 0 || !textureObject) {
|
||||
return;
|
||||
}
|
||||
const auto it = g_autoGenerateMipmapByTextureId.find(textureObject->GetExternalIndex());
|
||||
if (it == g_autoGenerateMipmapByTextureId.end() || !it->second) {
|
||||
return;
|
||||
}
|
||||
GenerateMipmap_Backend(target);
|
||||
}
|
||||
|
||||
void TexSubImage3D_State(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width,
|
||||
GLsizei height, GLsizei depth, GLenum format, GLenum type, const void* pixels) {
|
||||
// TODO: implement
|
||||
@@ -169,6 +182,7 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
|
||||
MGLOG_D("%s: mark mip %d as dirty", __func__, level);
|
||||
textureMipmapObject->MarkStorageDirty(textureUploadTarget, level, true);
|
||||
MaybeAutoGenerateMipmap(target, textureObject, false, level);
|
||||
}
|
||||
|
||||
void TexSubImage1D_State(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type,
|
||||
@@ -240,6 +254,9 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
case GL_TEXTURE_LOD_BIAS:
|
||||
textureObject->GetSamplerObject()->SetLodBias(param);
|
||||
break;
|
||||
case GL_GENERATE_MIPMAP:
|
||||
g_autoGenerateMipmapByTextureId[textureObject->GetExternalIndex()] = (param != 0.0f);
|
||||
break;
|
||||
case GL_TEXTURE_SWIZZLE_RGBA:
|
||||
// Not supported in this function
|
||||
case GL_TEXTURE_BORDER_COLOR:
|
||||
@@ -314,6 +331,9 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
case GL_TEXTURE_LOD_BIAS:
|
||||
textureObject->GetSamplerObject()->SetLodBias((GLfloat)param);
|
||||
break;
|
||||
case GL_GENERATE_MIPMAP:
|
||||
g_autoGenerateMipmapByTextureId[textureObject->GetExternalIndex()] = (param != GL_FALSE);
|
||||
break;
|
||||
case GL_TEXTURE_SWIZZLE_RGBA:
|
||||
// Not supported in this function
|
||||
case GL_TEXTURE_BORDER_COLOR:
|
||||
@@ -546,6 +566,10 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
if (!TextureImpl::ValidateTextureObject(textureObject)) return;
|
||||
|
||||
// ======================= Processing ================================
|
||||
if (internalformat == GL_ALPHA || format == GL_ALPHA) {
|
||||
textureObject->SetSwizzleParamRGBA({TextureSwizzleParam::Zero, TextureSwizzleParam::Zero,
|
||||
TextureSwizzleParam::Zero, TextureSwizzleParam::Red});
|
||||
}
|
||||
|
||||
SizeT imageSize = 0;
|
||||
const SizeT inputBpp = MG_Util::GetInputBytesPerPixel(textureInputFormat, texturePixelDataType);
|
||||
@@ -655,6 +679,10 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
if (!TextureImpl::ValidateTextureObject(textureObject)) return;
|
||||
|
||||
// ======================= Processing ================================
|
||||
if (internalformat == GL_ALPHA || format == GL_ALPHA) {
|
||||
textureObject->SetSwizzleParamRGBA({TextureSwizzleParam::Zero, TextureSwizzleParam::Zero,
|
||||
TextureSwizzleParam::Zero, TextureSwizzleParam::Red});
|
||||
}
|
||||
|
||||
SizeT imageSize = 0;
|
||||
const SizeT inputBpp = MG_Util::GetInputBytesPerPixel(textureInputFormat, texturePixelDataType);
|
||||
@@ -719,6 +747,7 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
|
||||
MGLOG_D("%s: mark mip %d as dirty", __func__, level);
|
||||
textureMipmapObject->MarkStorageDirty(textureUploadTarget, level, true);
|
||||
MaybeAutoGenerateMipmap(target, textureObject, isProxy, level);
|
||||
}
|
||||
|
||||
void TexImage1D_State(GLenum target, GLint level, GLint internalFormat, GLsizei width, GLint border, GLenum format,
|
||||
|
||||
@@ -48,6 +48,7 @@ namespace MobileGL {
|
||||
|
||||
TextureInputFormat ConvertGLEnumToTextureInputFormat(GLenum format) {
|
||||
switch (format) {
|
||||
case GL_ALPHA:
|
||||
case GL_RED:
|
||||
return TextureInputFormat::Red;
|
||||
case GL_RG:
|
||||
@@ -225,6 +226,7 @@ namespace MobileGL {
|
||||
return TextureInternalFormat::DepthComponent;
|
||||
case GL_DEPTH_STENCIL:
|
||||
return TextureInternalFormat::DepthStencil;
|
||||
case GL_ALPHA:
|
||||
case GL_RED:
|
||||
return TextureInternalFormat::Red;
|
||||
case GL_RG:
|
||||
|
||||
Reference in New Issue
Block a user