mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-12 14:18:31 +09:00
[Feat] (MG_Backend/DirectVulkan|MG_Util): Get Vulkan device info.
This commit is contained in:
@@ -168,6 +168,7 @@ set(SOURCE_FILES
|
|||||||
MobileGL/MG_Util/ShaderTranspiler/SpirvPasses/EliminateFloatEqualsZeroPass.cpp
|
MobileGL/MG_Util/ShaderTranspiler/SpirvPasses/EliminateFloatEqualsZeroPass.cpp
|
||||||
|
|
||||||
MobileGL/MG_Util/BackendLoaders/OpenGL/Loader.cpp
|
MobileGL/MG_Util/BackendLoaders/OpenGL/Loader.cpp
|
||||||
|
MobileGL/MG_Util/BackendLoaders/Vulkan/Loader.cpp
|
||||||
|
|
||||||
MobileGL/MG_Util/Texture/PixelStoreProcessor.cpp
|
MobileGL/MG_Util/Texture/PixelStoreProcessor.cpp
|
||||||
MobileGL/MG_Util/Texture/TextureFormatProcessor.cpp
|
MobileGL/MG_Util/Texture/TextureFormatProcessor.cpp
|
||||||
|
|||||||
@@ -9,8 +9,8 @@
|
|||||||
#include "BackendObject_DirectVulkan.h"
|
#include "BackendObject_DirectVulkan.h"
|
||||||
#include "MG_Backend/BackendObject.h"
|
#include "MG_Backend/BackendObject.h"
|
||||||
#include <MG_Backend/DirectVulkan/DirectVulkan.h>
|
#include <MG_Backend/DirectVulkan/DirectVulkan.h>
|
||||||
|
#include <MG_Backend/DirectVulkan/TmpImpl.h>
|
||||||
#include <MG_Util/BackendLoaders/OpenGL/Loader.h>
|
#include <MG_Util/BackendLoaders/OpenGL/Loader.h>
|
||||||
#include <format>
|
|
||||||
|
|
||||||
namespace MobileGL::MG_Backend::DirectVulkan {
|
namespace MobileGL::MG_Backend::DirectVulkan {
|
||||||
BackendObject_DirectVulkan::~BackendObject_DirectVulkan() = default;
|
BackendObject_DirectVulkan::~BackendObject_DirectVulkan() = default;
|
||||||
@@ -24,7 +24,16 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
|
|
||||||
void BackendObject_DirectVulkan::Initialize() {
|
void BackendObject_DirectVulkan::Initialize() {
|
||||||
m_initialized = true;
|
m_initialized = true;
|
||||||
// TODO
|
}
|
||||||
|
|
||||||
|
void BackendObject_DirectVulkan::InitCapabilities() {
|
||||||
|
if (!m_initialized) {
|
||||||
|
MGLOG_E("Cannot initialize capabilities before backend is initialized");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MG_Util::BackendLoader::QueryVulkanCapabilities(m_vulkanCaps,
|
||||||
|
DirectVulkan::GetVulkanState().ctx->GetPhysicalDevice());
|
||||||
UpdateDynamicBackendParameters();
|
UpdateDynamicBackendParameters();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,7 +62,9 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
// Format:
|
// Format:
|
||||||
// <GPU Name>, Vulkan <Vulkan Version>, Driver <Driver Version>
|
// <GPU Name>, Vulkan <Vulkan Version>, Driver <Driver Version>
|
||||||
// TODO
|
// TODO
|
||||||
return "Vulkan";
|
String str = m_vulkanCaps.DeviceName + ", Vulkan " + m_vulkanCaps.VulkanAPIVersion.toString() + ", Driver " +
|
||||||
|
m_vulkanCaps.DriverVersionString;
|
||||||
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
BackendType BackendObject_DirectVulkan::GetBackendType() const {
|
BackendType BackendObject_DirectVulkan::GetBackendType() const {
|
||||||
@@ -103,6 +114,6 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void BackendObject_DirectVulkan::UpdateDynamicBackendParameters() {
|
void BackendObject_DirectVulkan::UpdateDynamicBackendParameters() {
|
||||||
m_dynamicParameters.UniformBufferOffsetAlignment = 256; // TODO
|
m_dynamicParameters.UniformBufferOffsetAlignment = m_vulkanCaps.UniformBufferOffsetAlignment;
|
||||||
}
|
}
|
||||||
} // namespace MobileGL::MG_Backend::DirectVulkan
|
} // namespace MobileGL::MG_Backend::DirectVulkan
|
||||||
|
|||||||
@@ -9,13 +9,16 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <Includes.h>
|
#include <Includes.h>
|
||||||
#include "../BackendObject.h"
|
#include "../BackendObject.h"
|
||||||
|
#include <MG_Util/BackendLoaders/Vulkan/Loader.h>
|
||||||
|
|
||||||
namespace MobileGL::MG_Backend::DirectVulkan {
|
namespace MobileGL::MG_Backend::DirectVulkan {
|
||||||
class BackendObject_DirectVulkan : public BackendObject {
|
class BackendObject_DirectVulkan : public BackendObject {
|
||||||
public:
|
public:
|
||||||
~BackendObject_DirectVulkan() override;
|
~BackendObject_DirectVulkan() override;
|
||||||
|
|
||||||
void Initialize() override;
|
void Initialize() override;
|
||||||
void InitWindowSurface() override;
|
void InitWindowSurface() override;
|
||||||
|
void InitCapabilities() override;
|
||||||
|
|
||||||
const RendererInfo& GetRendererInfo() const override;
|
const RendererInfo& GetRendererInfo() const override;
|
||||||
String GetBackendAPIVersionString() const override;
|
String GetBackendAPIVersionString() const override;
|
||||||
@@ -28,5 +31,6 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
|
|
||||||
Bool m_initialized = false;
|
Bool m_initialized = false;
|
||||||
DynamicBackendParameters m_dynamicParameters;
|
DynamicBackendParameters m_dynamicParameters;
|
||||||
|
MG_External::VulkanCapabilities m_vulkanCaps;
|
||||||
};
|
};
|
||||||
} // namespace MobileGL::MG_Backend::DirectVulkan
|
} // namespace MobileGL::MG_Backend::DirectVulkan
|
||||||
|
|||||||
@@ -67,4 +67,8 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
void Present() {
|
void Present() {
|
||||||
TmpImpl::Present();
|
TmpImpl::Present();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const TmpImpl::VulkanState& GetVulkanState() {
|
||||||
|
return TmpImpl::GetVulkanState();
|
||||||
|
}
|
||||||
} // namespace MobileGL::MG_Backend::DirectVulkan
|
} // namespace MobileGL::MG_Backend::DirectVulkan
|
||||||
|
|||||||
@@ -11,6 +11,10 @@
|
|||||||
#include "Renderer/VulkanRenderer.h"
|
#include "Renderer/VulkanRenderer.h"
|
||||||
|
|
||||||
namespace MobileGL::MG_Backend::DirectVulkan {
|
namespace MobileGL::MG_Backend::DirectVulkan {
|
||||||
|
namespace TmpImpl {
|
||||||
|
class VulkanState;
|
||||||
|
} // namespace TmpImpl
|
||||||
|
|
||||||
void ClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);
|
void ClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);
|
||||||
void ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat* value);
|
void ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat* value);
|
||||||
void ClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint* value);
|
void ClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint* value);
|
||||||
@@ -51,4 +55,5 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
void GetTexImage(GLenum target, GLint level, GLenum format, GLenum type, GLvoid* pixels);
|
void GetTexImage(GLenum target, GLint level, GLenum format, GLenum type, GLvoid* pixels);
|
||||||
Bool InitWindowSurface(NativeWindowType window);
|
Bool InitWindowSurface(NativeWindowType window);
|
||||||
void Present();
|
void Present();
|
||||||
|
const TmpImpl::VulkanState& GetVulkanState();
|
||||||
} // namespace MobileGL::MG_Backend::DirectVulkan
|
} // namespace MobileGL::MG_Backend::DirectVulkan
|
||||||
|
|||||||
@@ -8,13 +8,6 @@
|
|||||||
|
|
||||||
#include "TmpImpl.h"
|
#include "TmpImpl.h"
|
||||||
#include "MG_Backend/DirectVulkan/DirectVulkan.h"
|
#include "MG_Backend/DirectVulkan/DirectVulkan.h"
|
||||||
#include "MG_Util/Types.h"
|
|
||||||
#include "Renderer/VkCommon.h"
|
|
||||||
#include "Renderer/VulkanContext.h"
|
|
||||||
#include "Renderer/SwapchainManager.h"
|
|
||||||
#include "Renderer/FrameContext.h"
|
|
||||||
#include "Managers/ProgramManager.h"
|
|
||||||
#include <MG_State/GLState/Core.h>
|
|
||||||
#include <MG_Impl/GLImpl/Framebuffer/GL_Framebuffer.h>
|
#include <MG_Impl/GLImpl/Framebuffer/GL_Framebuffer.h>
|
||||||
#include <MG_Util/ShaderTranspiler/Types.h>
|
#include <MG_Util/ShaderTranspiler/Types.h>
|
||||||
#include "MG_Util/Debug/Log.h"
|
#include "MG_Util/Debug/Log.h"
|
||||||
@@ -22,222 +15,10 @@
|
|||||||
|
|
||||||
#define DEBUG_TRACE_POINT() MGLOG_D("DV TmpImpl Trace: %s:%d", __func__, __LINE__)
|
#define DEBUG_TRACE_POINT() MGLOG_D("DV TmpImpl Trace: %s:%d", __func__, __LINE__)
|
||||||
namespace MobileGL::MG_Backend::DirectVulkan::TmpImpl {
|
namespace MobileGL::MG_Backend::DirectVulkan::TmpImpl {
|
||||||
namespace {
|
|
||||||
class PendingClearInfo;
|
class PendingClearInfo;
|
||||||
void BeginRenderPass(GLbitfield clearMask, const PendingClearInfo* clearInfo);
|
void BeginRenderPass(GLbitfield clearMask, const PendingClearInfo* clearInfo);
|
||||||
namespace DV = MobileGL::MG_Backend::DirectVulkan::VkManager;
|
|
||||||
using BufferObject = MobileGL::MG_State::GLState::BufferObject;
|
|
||||||
using ProgramObject = MobileGL::MG_State::GLState::ProgramObject;
|
|
||||||
using VertexArrayObject = MobileGL::MG_State::GLState::VertexArrayObject;
|
|
||||||
using FramebufferObject = MobileGL::MG_State::GLState::FramebufferObject;
|
|
||||||
using FramebufferAttachmentObject = MobileGL::MG_State::GLState::FramebufferAttachmentObject;
|
|
||||||
using ITextureObject = MobileGL::MG_State::GLState::ITextureObject;
|
|
||||||
using RenderbufferObject = MobileGL::MG_State::GLState::RenderbufferObject;
|
|
||||||
using SamplerObject = MobileGL::MG_State::GLState::SamplerObject;
|
|
||||||
using TextureObjectMipmap = MobileGL::MG_State::GLState::TextureObjectMipmap;
|
|
||||||
using TrashImage = MobileGL::MG_Backend::DirectVulkan::TrashImage;
|
|
||||||
|
|
||||||
struct BufferResource {
|
VulkanState g;
|
||||||
VkBuffer buffer = VK_NULL_HANDLE;
|
|
||||||
VkDeviceMemory memory = VK_NULL_HANDLE;
|
|
||||||
VkDeviceSize size = 0;
|
|
||||||
VkBufferUsageFlags usage = 0;
|
|
||||||
VkMemoryPropertyFlags props = 0;
|
|
||||||
void* mapped = nullptr;
|
|
||||||
Uint32 lastUsedFrame = ~0u;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct TextureResource {
|
|
||||||
VkImage image = VK_NULL_HANDLE;
|
|
||||||
VkDeviceMemory memory = VK_NULL_HANDLE;
|
|
||||||
VkImageView view = VK_NULL_HANDLE;
|
|
||||||
UnorderedMap<Uint32, VkImageView> mipViews;
|
|
||||||
VkFormat format = VK_FORMAT_UNDEFINED;
|
|
||||||
VkExtent3D extent{0, 0, 1};
|
|
||||||
VkImageLayout layout = VK_IMAGE_LAYOUT_UNDEFINED;
|
|
||||||
Uint32 mipLevels = 1;
|
|
||||||
Uint16 paramsVersion = 0;
|
|
||||||
bool valid = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct RenderbufferResource {
|
|
||||||
VkImage image = VK_NULL_HANDLE;
|
|
||||||
VkDeviceMemory memory = VK_NULL_HANDLE;
|
|
||||||
VkImageView view = VK_NULL_HANDLE;
|
|
||||||
VkFormat format = VK_FORMAT_UNDEFINED;
|
|
||||||
VkExtent2D extent{0, 0};
|
|
||||||
VkImageLayout layout = VK_IMAGE_LAYOUT_UNDEFINED;
|
|
||||||
bool valid = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SamplerResource {
|
|
||||||
VkSampler sampler = VK_NULL_HANDLE;
|
|
||||||
Uint16 version = 0;
|
|
||||||
SamplerParameters params{};
|
|
||||||
};
|
|
||||||
|
|
||||||
struct PendingClearInfo {
|
|
||||||
GLbitfield mask = 0;
|
|
||||||
FloatVec4 clearColor = {0.0f, 0.0f, 0.0f, 1.0f};
|
|
||||||
Float clearDepth = 1.0f;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct UniformBindingInfo {
|
|
||||||
String name;
|
|
||||||
Uint32 binding = 0;
|
|
||||||
Uint32 set = 0;
|
|
||||||
Uint32 blockIndex = 0xFFFFFFFFu;
|
|
||||||
VkShaderStageFlags stages = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SamplerBindingInfo {
|
|
||||||
String name;
|
|
||||||
Uint32 binding = 0;
|
|
||||||
Uint32 set = 0;
|
|
||||||
VkShaderStageFlags stages = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ProgramResource {
|
|
||||||
ProgramObject* program = nullptr;
|
|
||||||
Uint64 spvHash = 0;
|
|
||||||
DV::ProgramManager::HashType programHash = 0;
|
|
||||||
Vector<VkPipelineShaderStageCreateInfo>* shaderStages = nullptr;
|
|
||||||
|
|
||||||
VkDescriptorSetLayout setLayout = VK_NULL_HANDLE;
|
|
||||||
VkPipelineLayout pipelineLayout = VK_NULL_HANDLE;
|
|
||||||
|
|
||||||
struct UboPool {
|
|
||||||
Vector<BufferResource> buffers;
|
|
||||||
Uint32 cursor = 0;
|
|
||||||
};
|
|
||||||
Vector<UboPool> uboPools;
|
|
||||||
SizeT uboSize = 0;
|
|
||||||
Int32 uboBinding = -1;
|
|
||||||
Uint32 uniformDescriptorCount = 0;
|
|
||||||
Uint32 samplerDescriptorCount = 0;
|
|
||||||
|
|
||||||
Vector<UniformBindingInfo> uniformBindings;
|
|
||||||
Vector<SamplerBindingInfo> samplerBindings;
|
|
||||||
UnorderedMap<String, Uint32> samplerBindingByName;
|
|
||||||
|
|
||||||
UnorderedMap<Uint64, VkPipeline> pipelines;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct DescriptorPoolConfig {
|
|
||||||
Uint32 maxSets = 0;
|
|
||||||
Uint32 uniformCount = 0;
|
|
||||||
Uint32 samplerCount = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct FrameDescriptorPools {
|
|
||||||
Vector<VkDescriptorPool> pools;
|
|
||||||
DescriptorPoolConfig config;
|
|
||||||
Uint32 activePool = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct VertexAttribKey {
|
|
||||||
Uint8 enabled = 0;
|
|
||||||
Uint8 size = 0;
|
|
||||||
Uint8 type = 0;
|
|
||||||
Uint8 normalized = 0;
|
|
||||||
Uint8 isInteger = 0;
|
|
||||||
Uint8 divisor = 0;
|
|
||||||
Uint16 pad = 0;
|
|
||||||
Uint32 stride = 0;
|
|
||||||
Uint64 offset = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct AttachmentInfo {
|
|
||||||
FramebufferAttachmentType type = FramebufferAttachmentType::None;
|
|
||||||
VkImageView view = VK_NULL_HANDLE;
|
|
||||||
VkFormat format = VK_FORMAT_UNDEFINED;
|
|
||||||
VkImageAspectFlags aspect = 0;
|
|
||||||
VkImageLayout finalLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
|
||||||
ITextureObject* texture = nullptr;
|
|
||||||
RenderbufferObject* renderbuffer = nullptr;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct BackendFramebufferObject {
|
|
||||||
Array<VkRenderPass, 8> renderPasses = {};
|
|
||||||
VkFramebuffer framebuffer = VK_NULL_HANDLE;
|
|
||||||
VkExtent2D extent{0, 0};
|
|
||||||
Uint32 colorAttachmentCount = 0;
|
|
||||||
Bool hasDepth = false;
|
|
||||||
VkFormat depthFormat = VK_FORMAT_UNDEFINED;
|
|
||||||
Uint64 renderPassCompatHash = 0;
|
|
||||||
|
|
||||||
Vector<AttachmentInfo> attachments;
|
|
||||||
Array<Int32, static_cast<SizeT>(FramebufferAttachmentType::FramebufferAttachmentTypeCount)>
|
|
||||||
attachmentIndex = {};
|
|
||||||
|
|
||||||
FramebufferObject::FramebufferAttachmentVersionArray syncedAttachmentVersions = {0};
|
|
||||||
FramebufferObject::FramebufferAttachmentArray frontendDrawBuffers = {FramebufferAttachmentType::None};
|
|
||||||
Array<Int32, FramebufferObject::MAX_DRAW_BUFFERS> drawBufferAttachmentIndices = {};
|
|
||||||
FramebufferAttachmentType frontendReadBuffer = FramebufferAttachmentType::Color0;
|
|
||||||
Uint64 configHash = 0;
|
|
||||||
Uint16 objectVersion = 0;
|
|
||||||
|
|
||||||
Bool IsValid() const { return renderPasses[0] != VK_NULL_HANDLE && framebuffer != VK_NULL_HANDLE; }
|
|
||||||
};
|
|
||||||
|
|
||||||
struct BackendState {
|
|
||||||
UniquePtr<DV::VulkanContext> ctx;
|
|
||||||
UniquePtr<DV::SwapchainManager> swapchain;
|
|
||||||
UniquePtr<DV::ProgramManager> programMgr;
|
|
||||||
Array<VkRenderPass, 8> renderPasses = {};
|
|
||||||
VkCommandPool commandPool = VK_NULL_HANDLE;
|
|
||||||
Vector<UniquePtr<DV::FrameContext>> frames;
|
|
||||||
Vector<FrameDescriptorPools> frameDescriptorPools;
|
|
||||||
Uint32 currentFrame = 0;
|
|
||||||
Uint32 maxFramesInFlight = 2;
|
|
||||||
Bool initialized = false;
|
|
||||||
UintVec2 viewportSize{0, 0};
|
|
||||||
|
|
||||||
VkImage depthImage = VK_NULL_HANDLE;
|
|
||||||
VkDeviceMemory depthMemory = VK_NULL_HANDLE;
|
|
||||||
VkImageView depthView = VK_NULL_HANDLE;
|
|
||||||
VkFormat depthFormat = VK_FORMAT_UNDEFINED;
|
|
||||||
Uint64 defaultRenderPassCompatHash = 0;
|
|
||||||
|
|
||||||
BufferResource nullUbo;
|
|
||||||
|
|
||||||
TextureResource defaultTexture;
|
|
||||||
SamplerResource defaultSampler;
|
|
||||||
|
|
||||||
UnorderedMap<const BufferObject*, BufferResource> buffers;
|
|
||||||
UnorderedMap<const ITextureObject*, TextureResource> textures;
|
|
||||||
UnorderedMap<const RenderbufferObject*, RenderbufferResource> renderbuffers;
|
|
||||||
UnorderedMap<const SamplerObject*, SamplerResource> samplers;
|
|
||||||
UnorderedMap<const ProgramObject*, ProgramResource> programs;
|
|
||||||
UnorderedMap<SharedPtr<MG_State::GLState::FramebufferObject>, SharedPtr<BackendFramebufferObject>>
|
|
||||||
framebuffers;
|
|
||||||
|
|
||||||
VkRenderPass activeRenderPass = VK_NULL_HANDLE;
|
|
||||||
VkFramebuffer activeFramebuffer = VK_NULL_HANDLE;
|
|
||||||
VkExtent2D activeExtent{0, 0};
|
|
||||||
Uint32 activeColorAttachmentCount = 1;
|
|
||||||
Bool activeHasDepth = false;
|
|
||||||
VkFormat activeDepthFormat = VK_FORMAT_UNDEFINED;
|
|
||||||
SharedPtr<MG_State::GLState::FramebufferObject> activeStateFBO = nullptr;
|
|
||||||
SharedPtr<BackendFramebufferObject> activeBackendFBO = nullptr;
|
|
||||||
Bool activeIsDefault = true;
|
|
||||||
Bool activeDefaultColorWrites = true;
|
|
||||||
|
|
||||||
VkRenderPass recordingRenderPass = VK_NULL_HANDLE;
|
|
||||||
VkFramebuffer recordingFramebuffer = VK_NULL_HANDLE;
|
|
||||||
Bool cmdBufferBegun = false;
|
|
||||||
|
|
||||||
Bool recording = false;
|
|
||||||
Bool frameSubmitted = false;
|
|
||||||
FloatVec4 clearColor = {0.0f, 0.0f, 0.0f, 1.0f};
|
|
||||||
Float clearDepth = 1.0f;
|
|
||||||
|
|
||||||
UnorderedMap<SharedPtr<FramebufferObject>, PendingClearInfo> pendingClears;
|
|
||||||
|
|
||||||
Vector<VkImageLayout> swapchainImageLayouts;
|
|
||||||
};
|
|
||||||
|
|
||||||
BackendState g;
|
|
||||||
|
|
||||||
void ClearFrameTrashBuffers();
|
void ClearFrameTrashBuffers();
|
||||||
void ClearFrameTrashImages();
|
void ClearFrameTrashImages();
|
||||||
@@ -269,8 +50,7 @@ namespace MobileGL::MG_Backend::DirectVulkan::TmpImpl {
|
|||||||
res.size = 0;
|
res.size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CreateBuffer(VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags props,
|
void CreateBuffer(VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags props, BufferResource& out) {
|
||||||
BufferResource& out) {
|
|
||||||
VkBufferCreateInfo bci{VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO};
|
VkBufferCreateInfo bci{VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO};
|
||||||
bci.size = size;
|
bci.size = size;
|
||||||
bci.usage = usage;
|
bci.usage = usage;
|
||||||
@@ -346,8 +126,7 @@ namespace MobileGL::MG_Backend::DirectVulkan::TmpImpl {
|
|||||||
VkBufferUsageFlags usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT |
|
VkBufferUsageFlags usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT |
|
||||||
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT |
|
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT |
|
||||||
VK_BUFFER_USAGE_TRANSFER_DST_BIT;
|
VK_BUFFER_USAGE_TRANSFER_DST_BIT;
|
||||||
VkMemoryPropertyFlags props =
|
VkMemoryPropertyFlags props = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
|
||||||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
|
|
||||||
CreateBuffer(size, usage, props, res);
|
CreateBuffer(size, usage, props, res);
|
||||||
res.lastUsedFrame = ~0u;
|
res.lastUsedFrame = ~0u;
|
||||||
}
|
}
|
||||||
@@ -705,8 +484,7 @@ namespace MobileGL::MG_Backend::DirectVulkan::TmpImpl {
|
|||||||
VkAttachmentDescription depth{};
|
VkAttachmentDescription depth{};
|
||||||
depth.format = g.depthFormat;
|
depth.format = g.depthFormat;
|
||||||
depth.samples = VK_SAMPLE_COUNT_1_BIT;
|
depth.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||||
depth.loadOp =
|
depth.loadOp = (clearMask & GL_DEPTH_BUFFER_BIT) ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||||
(clearMask & GL_DEPTH_BUFFER_BIT) ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD;
|
|
||||||
depth.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
depth.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||||
if (AspectForFormat(g.depthFormat) & VK_IMAGE_ASPECT_STENCIL_BIT) {
|
if (AspectForFormat(g.depthFormat) & VK_IMAGE_ASPECT_STENCIL_BIT) {
|
||||||
depth.stencilLoadOp =
|
depth.stencilLoadOp =
|
||||||
@@ -855,8 +633,8 @@ namespace MobileGL::MG_Backend::DirectVulkan::TmpImpl {
|
|||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CmdTransitionImageLayout(VkCommandBuffer cmd, VkImage image, VkImageLayout oldLayout,
|
void CmdTransitionImageLayout(VkCommandBuffer cmd, VkImage image, VkImageLayout oldLayout, VkImageLayout newLayout,
|
||||||
VkImageLayout newLayout, VkImageAspectFlags aspect) {
|
VkImageAspectFlags aspect) {
|
||||||
VkImageMemoryBarrier barrier{VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER};
|
VkImageMemoryBarrier barrier{VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER};
|
||||||
barrier.oldLayout = oldLayout;
|
barrier.oldLayout = oldLayout;
|
||||||
barrier.newLayout = newLayout;
|
barrier.newLayout = newLayout;
|
||||||
@@ -889,8 +667,7 @@ namespace MobileGL::MG_Backend::DirectVulkan::TmpImpl {
|
|||||||
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
|
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
|
||||||
srcStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
|
srcStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
|
||||||
dstStage = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
|
dstStage = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
|
||||||
} else if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED &&
|
} else if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && newLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) {
|
||||||
newLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) {
|
|
||||||
barrier.srcAccessMask = 0;
|
barrier.srcAccessMask = 0;
|
||||||
barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
|
barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
|
||||||
srcStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
|
srcStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
|
||||||
@@ -901,8 +678,7 @@ namespace MobileGL::MG_Backend::DirectVulkan::TmpImpl {
|
|||||||
barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
|
barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
|
||||||
srcStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
|
srcStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
|
||||||
dstStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
|
dstStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
|
||||||
} else if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED &&
|
} else if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && newLayout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) {
|
||||||
newLayout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) {
|
|
||||||
barrier.srcAccessMask = 0;
|
barrier.srcAccessMask = 0;
|
||||||
barrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
barrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
||||||
srcStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
|
srcStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
|
||||||
@@ -951,26 +727,22 @@ namespace MobileGL::MG_Backend::DirectVulkan::TmpImpl {
|
|||||||
barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
|
barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
|
||||||
srcStage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
srcStage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||||
dstStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
|
dstStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
|
||||||
} else if (oldLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR &&
|
} else if (oldLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR && newLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL) {
|
||||||
newLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL) {
|
|
||||||
barrier.srcAccessMask = 0;
|
barrier.srcAccessMask = 0;
|
||||||
barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
|
barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
|
||||||
srcStage = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
|
srcStage = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
|
||||||
dstStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
|
dstStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
|
||||||
} else if (oldLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR &&
|
} else if (oldLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR && newLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) {
|
||||||
newLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) {
|
|
||||||
barrier.srcAccessMask = 0;
|
barrier.srcAccessMask = 0;
|
||||||
barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||||
srcStage = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
|
srcStage = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
|
||||||
dstStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
|
dstStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
|
||||||
} else if (oldLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL &&
|
} else if (oldLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL && newLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR) {
|
||||||
newLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR) {
|
|
||||||
barrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
|
barrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
|
||||||
barrier.dstAccessMask = 0;
|
barrier.dstAccessMask = 0;
|
||||||
srcStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
|
srcStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
|
||||||
dstStage = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
|
dstStage = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
|
||||||
} else if (oldLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL &&
|
} else if (oldLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL && newLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR) {
|
||||||
newLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR) {
|
|
||||||
barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||||
barrier.dstAccessMask = 0;
|
barrier.dstAccessMask = 0;
|
||||||
srcStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
|
srcStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
|
||||||
@@ -1023,14 +795,12 @@ namespace MobileGL::MG_Backend::DirectVulkan::TmpImpl {
|
|||||||
void EnsureImageLayout(VkImage image, VkImageLayout& currentLayout, VkImageLayout desiredLayout,
|
void EnsureImageLayout(VkImage image, VkImageLayout& currentLayout, VkImageLayout desiredLayout,
|
||||||
VkImageAspectFlags aspect) {
|
VkImageAspectFlags aspect) {
|
||||||
if (currentLayout == desiredLayout) return;
|
if (currentLayout == desiredLayout) return;
|
||||||
SubmitImmediate([&](VkCommandBuffer cmd) {
|
SubmitImmediate(
|
||||||
CmdTransitionImageLayout(cmd, image, currentLayout, desiredLayout, aspect);
|
[&](VkCommandBuffer cmd) { CmdTransitionImageLayout(cmd, image, currentLayout, desiredLayout, aspect); });
|
||||||
});
|
|
||||||
currentLayout = desiredLayout;
|
currentLayout = desiredLayout;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EnsureImageLayoutForDescriptor(TextureResource& res, VkImageAspectFlags aspect,
|
void EnsureImageLayoutForDescriptor(TextureResource& res, VkImageAspectFlags aspect, VkImageLayout desiredLayout) {
|
||||||
VkImageLayout desiredLayout) {
|
|
||||||
if (res.image == VK_NULL_HANDLE) return;
|
if (res.image == VK_NULL_HANDLE) return;
|
||||||
if (res.layout == desiredLayout) return;
|
if (res.layout == desiredLayout) return;
|
||||||
if (!g.cmdBufferBegun) {
|
if (!g.cmdBufferBegun) {
|
||||||
@@ -1098,8 +868,7 @@ namespace MobileGL::MG_Backend::DirectVulkan::TmpImpl {
|
|||||||
region.imageSubresource.baseArrayLayer = 0;
|
region.imageSubresource.baseArrayLayer = 0;
|
||||||
region.imageSubresource.layerCount = 1;
|
region.imageSubresource.layerCount = 1;
|
||||||
region.imageExtent = extent;
|
region.imageExtent = extent;
|
||||||
vkCmdCopyBufferToImage(cmd, staging.buffer, res.image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1,
|
vkCmdCopyBufferToImage(cmd, staging.buffer, res.image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion);
|
||||||
®ion);
|
|
||||||
|
|
||||||
CmdTransitionImageLayout(cmd, res.image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, sampledLayout, aspect);
|
CmdTransitionImageLayout(cmd, res.image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, sampledLayout, aspect);
|
||||||
});
|
});
|
||||||
@@ -1127,8 +896,7 @@ namespace MobileGL::MG_Backend::DirectVulkan::TmpImpl {
|
|||||||
region.srcSubresource.baseArrayLayer = 0;
|
region.srcSubresource.baseArrayLayer = 0;
|
||||||
region.srcSubresource.layerCount = 1;
|
region.srcSubresource.layerCount = 1;
|
||||||
region.dstSubresource = region.srcSubresource;
|
region.dstSubresource = region.srcSubresource;
|
||||||
region.extent = {std::max(1u, dst.extent.width >> level), std::max(1u, dst.extent.height >> level),
|
region.extent = {std::max(1u, dst.extent.width >> level), std::max(1u, dst.extent.height >> level), 1};
|
||||||
1};
|
|
||||||
vkCmdCopyImage(cmd, src.image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dst.image,
|
vkCmdCopyImage(cmd, src.image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dst.image,
|
||||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion);
|
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion);
|
||||||
}
|
}
|
||||||
@@ -1144,8 +912,7 @@ namespace MobileGL::MG_Backend::DirectVulkan::TmpImpl {
|
|||||||
auto& res = g.textures[tex];
|
auto& res = g.textures[tex];
|
||||||
VkFormat fmt = ToVkFormat(tex->GetFormat());
|
VkFormat fmt = ToVkFormat(tex->GetFormat());
|
||||||
auto size = tex->GetBaseSize();
|
auto size = tex->GetBaseSize();
|
||||||
VkExtent3D extent{static_cast<Uint32>(std::max(1, size.x())), static_cast<Uint32>(std::max(1, size.y())),
|
VkExtent3D extent{static_cast<Uint32>(std::max(1, size.x())), static_cast<Uint32>(std::max(1, size.y())), 1};
|
||||||
1};
|
|
||||||
Uint32 mipLevels = 1;
|
Uint32 mipLevels = 1;
|
||||||
if (tex->GetStorageType() == TextureStorageType::Mipmap) {
|
if (tex->GetStorageType() == TextureStorageType::Mipmap) {
|
||||||
auto* mip = dynamic_cast<TextureObjectMipmap*>(tex);
|
auto* mip = dynamic_cast<TextureObjectMipmap*>(tex);
|
||||||
@@ -1174,8 +941,7 @@ namespace MobileGL::MG_Backend::DirectVulkan::TmpImpl {
|
|||||||
if (canCopy) {
|
if (canCopy) {
|
||||||
CopyImageMipLevels(oldRes, res);
|
CopyImageMipLevels(oldRes, res);
|
||||||
}
|
}
|
||||||
if (oldRes.image != VK_NULL_HANDLE || oldRes.view != VK_NULL_HANDLE ||
|
if (oldRes.image != VK_NULL_HANDLE || oldRes.view != VK_NULL_HANDLE || oldRes.memory != VK_NULL_HANDLE) {
|
||||||
oldRes.memory != VK_NULL_HANDLE) {
|
|
||||||
TrashImageResource(oldRes);
|
TrashImageResource(oldRes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1195,8 +961,8 @@ namespace MobileGL::MG_Backend::DirectVulkan::TmpImpl {
|
|||||||
VkExtent2D extent{static_cast<Uint32>(std::max(1, rbo->GetWidth())),
|
VkExtent2D extent{static_cast<Uint32>(std::max(1, rbo->GetWidth())),
|
||||||
static_cast<Uint32>(std::max(1, rbo->GetHeight()))};
|
static_cast<Uint32>(std::max(1, rbo->GetHeight()))};
|
||||||
|
|
||||||
Bool needCreate = !res.valid || res.format != fmt || res.extent.width != extent.width ||
|
Bool needCreate =
|
||||||
res.extent.height != extent.height;
|
!res.valid || res.format != fmt || res.extent.width != extent.width || res.extent.height != extent.height;
|
||||||
if (needCreate) {
|
if (needCreate) {
|
||||||
DestroyRenderbuffer(res);
|
DestroyRenderbuffer(res);
|
||||||
res.format = fmt;
|
res.format = fmt;
|
||||||
@@ -1373,8 +1139,7 @@ namespace MobileGL::MG_Backend::DirectVulkan::TmpImpl {
|
|||||||
}
|
}
|
||||||
Int32 idx = newIndex[static_cast<SizeT>(buf)];
|
Int32 idx = newIndex[static_cast<SizeT>(buf)];
|
||||||
if (idx < 0) {
|
if (idx < 0) {
|
||||||
MGLOG_W("Framebuffer %u draw buffer %u refers to missing attachment", stateFBO->GetExternalIndex(),
|
MGLOG_W("Framebuffer %u draw buffer %u refers to missing attachment", stateFBO->GetExternalIndex(), i);
|
||||||
i);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
drawAttachmentIndices[i] = idx;
|
drawAttachmentIndices[i] = idx;
|
||||||
@@ -1472,8 +1237,7 @@ namespace MobileGL::MG_Backend::DirectVulkan::TmpImpl {
|
|||||||
fbci.width = extent.width;
|
fbci.width = extent.width;
|
||||||
fbci.height = extent.height;
|
fbci.height = extent.height;
|
||||||
fbci.layers = 1;
|
fbci.layers = 1;
|
||||||
VK_VERIFY(vkCreateFramebuffer(g.ctx->GetDevice(), &fbci, nullptr, &backend.framebuffer),
|
VK_VERIFY(vkCreateFramebuffer(g.ctx->GetDevice(), &fbci, nullptr, &backend.framebuffer), "vkCreateFramebuffer");
|
||||||
"vkCreateFramebuffer");
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -1780,11 +1544,9 @@ namespace MobileGL::MG_Backend::DirectVulkan::TmpImpl {
|
|||||||
if (normalized) {
|
if (normalized) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case DataType::Int8:
|
case DataType::Int8:
|
||||||
return pick(VK_FORMAT_R8_SNORM, VK_FORMAT_R8G8_SNORM, VK_FORMAT_R8G8B8_SNORM,
|
return pick(VK_FORMAT_R8_SNORM, VK_FORMAT_R8G8_SNORM, VK_FORMAT_R8G8B8_SNORM, VK_FORMAT_R8G8B8A8_SNORM);
|
||||||
VK_FORMAT_R8G8B8A8_SNORM);
|
|
||||||
case DataType::Uint8:
|
case DataType::Uint8:
|
||||||
return pick(VK_FORMAT_R8_UNORM, VK_FORMAT_R8G8_UNORM, VK_FORMAT_R8G8B8_UNORM,
|
return pick(VK_FORMAT_R8_UNORM, VK_FORMAT_R8G8_UNORM, VK_FORMAT_R8G8B8_UNORM, VK_FORMAT_R8G8B8A8_UNORM);
|
||||||
VK_FORMAT_R8G8B8A8_UNORM);
|
|
||||||
case DataType::Int16:
|
case DataType::Int16:
|
||||||
return pick(VK_FORMAT_R16_SNORM, VK_FORMAT_R16G16_SNORM, VK_FORMAT_R16G16B16_SNORM,
|
return pick(VK_FORMAT_R16_SNORM, VK_FORMAT_R16G16_SNORM, VK_FORMAT_R16G16B16_SNORM,
|
||||||
VK_FORMAT_R16G16B16A16_SNORM);
|
VK_FORMAT_R16G16B16A16_SNORM);
|
||||||
@@ -1951,8 +1713,7 @@ namespace MobileGL::MG_Backend::DirectVulkan::TmpImpl {
|
|||||||
spvc_parsed_ir ir = nullptr;
|
spvc_parsed_ir ir = nullptr;
|
||||||
spvc_context_parse_spirv(context, spv.data(), spv.size(), &ir);
|
spvc_context_parse_spirv(context, spv.data(), spv.size(), &ir);
|
||||||
spvc_compiler compiler = nullptr;
|
spvc_compiler compiler = nullptr;
|
||||||
spvc_context_create_compiler(context, SPVC_BACKEND_GLSL, ir, SPVC_CAPTURE_MODE_TAKE_OWNERSHIP,
|
spvc_context_create_compiler(context, SPVC_BACKEND_GLSL, ir, SPVC_CAPTURE_MODE_TAKE_OWNERSHIP, &compiler);
|
||||||
&compiler);
|
|
||||||
spvc_resources resources = nullptr;
|
spvc_resources resources = nullptr;
|
||||||
spvc_compiler_create_shader_resources(compiler, &resources);
|
spvc_compiler_create_shader_resources(compiler, &resources);
|
||||||
|
|
||||||
@@ -2247,10 +2008,9 @@ namespace MobileGL::MG_Backend::DirectVulkan::TmpImpl {
|
|||||||
return XXH64(keys, sizeof(keys), 0xBADC0FFEEu);
|
return XXH64(keys, sizeof(keys), 0xBADC0FFEEu);
|
||||||
}
|
}
|
||||||
|
|
||||||
VkPipeline GetOrCreatePipeline(ProgramResource& prog, const VertexArrayObject* vao,
|
VkPipeline GetOrCreatePipeline(ProgramResource& prog, const VertexArrayObject* vao, const RenderStateParameters& rs,
|
||||||
const RenderStateParameters& rs, VkPrimitiveTopology topology,
|
VkPrimitiveTopology topology, VkRenderPass renderPass, Uint32 colorAttachmentCount,
|
||||||
VkRenderPass renderPass, Uint32 colorAttachmentCount, Bool hasDepth,
|
Bool hasDepth, Uint64 renderPassKey) {
|
||||||
Uint64 renderPassKey) {
|
|
||||||
if (!g.programMgr) g.programMgr = MakeUnique<DV::ProgramManager>(*g.ctx);
|
if (!g.programMgr) g.programMgr = MakeUnique<DV::ProgramManager>(*g.ctx);
|
||||||
prog.shaderStages = &g.programMgr->CreatePipelineShaderStages(prog.program, GetShaderTransformFlags());
|
prog.shaderStages = &g.programMgr->CreatePipelineShaderStages(prog.program, GetShaderTransformFlags());
|
||||||
if (!prog.shaderStages || prog.shaderStages->empty()) {
|
if (!prog.shaderStages || prog.shaderStages->empty()) {
|
||||||
@@ -2597,8 +2357,8 @@ namespace MobileGL::MG_Backend::DirectVulkan::TmpImpl {
|
|||||||
g.defaultTexture.extent = {1, 1, 1};
|
g.defaultTexture.extent = {1, 1, 1};
|
||||||
g.defaultTexture.mipLevels = 1;
|
g.defaultTexture.mipLevels = 1;
|
||||||
CreateImage(g.defaultTexture.extent, g.defaultTexture.format,
|
CreateImage(g.defaultTexture.extent, g.defaultTexture.format,
|
||||||
UsageForTextureFormat(g.defaultTexture.format), g.defaultTexture.image,
|
UsageForTextureFormat(g.defaultTexture.format), g.defaultTexture.image, g.defaultTexture.memory,
|
||||||
g.defaultTexture.memory, g.defaultTexture.mipLevels);
|
g.defaultTexture.mipLevels);
|
||||||
g.defaultTexture.view =
|
g.defaultTexture.view =
|
||||||
CreateImageView(g.defaultTexture.image, g.defaultTexture.format, VK_IMAGE_ASPECT_COLOR_BIT);
|
CreateImageView(g.defaultTexture.image, g.defaultTexture.format, VK_IMAGE_ASPECT_COLOR_BIT);
|
||||||
g.defaultTexture.layout = VK_IMAGE_LAYOUT_UNDEFINED;
|
g.defaultTexture.layout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||||
@@ -2673,8 +2433,7 @@ namespace MobileGL::MG_Backend::DirectVulkan::TmpImpl {
|
|||||||
|
|
||||||
SubmitImmediate([&](VkCommandBuffer cmd) {
|
SubmitImmediate([&](VkCommandBuffer cmd) {
|
||||||
CmdTransitionImageLayout(cmd, g.depthImage, VK_IMAGE_LAYOUT_UNDEFINED,
|
CmdTransitionImageLayout(cmd, g.depthImage, VK_IMAGE_LAYOUT_UNDEFINED,
|
||||||
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
|
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, AspectForFormat(g.depthFormat));
|
||||||
AspectForFormat(g.depthFormat));
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2753,8 +2512,7 @@ namespace MobileGL::MG_Backend::DirectVulkan::TmpImpl {
|
|||||||
void BeginCommandBuffer() {
|
void BeginCommandBuffer() {
|
||||||
if (g.cmdBufferBegun) return;
|
if (g.cmdBufferBegun) return;
|
||||||
auto& frame = *g.frames[g.currentFrame];
|
auto& frame = *g.frames[g.currentFrame];
|
||||||
VK_VERIFY(vkWaitForFences(g.ctx->GetDevice(), 1, &frame.InFlightFence, VK_TRUE, UINT64_MAX),
|
VK_VERIFY(vkWaitForFences(g.ctx->GetDevice(), 1, &frame.InFlightFence, VK_TRUE, UINT64_MAX), "vkWaitForFences");
|
||||||
"vkWaitForFences");
|
|
||||||
VK_VERIFY(vkResetFences(g.ctx->GetDevice(), 1, &frame.InFlightFence), "vkResetFences");
|
VK_VERIFY(vkResetFences(g.ctx->GetDevice(), 1, &frame.InFlightFence), "vkResetFences");
|
||||||
ClearFrameTrashBuffers();
|
ClearFrameTrashBuffers();
|
||||||
ClearFrameTrashImages();
|
ClearFrameTrashImages();
|
||||||
@@ -2853,8 +2611,7 @@ namespace MobileGL::MG_Backend::DirectVulkan::TmpImpl {
|
|||||||
if ((pendingMask & GL_DEPTH_BUFFER_BIT) && g.activeHasDepth && (depthAspect & VK_IMAGE_ASPECT_DEPTH_BIT)) {
|
if ((pendingMask & GL_DEPTH_BUFFER_BIT) && g.activeHasDepth && (depthAspect & VK_IMAGE_ASPECT_DEPTH_BIT)) {
|
||||||
effectiveMask |= GL_DEPTH_BUFFER_BIT;
|
effectiveMask |= GL_DEPTH_BUFFER_BIT;
|
||||||
}
|
}
|
||||||
if ((pendingMask & GL_STENCIL_BUFFER_BIT) && g.activeHasDepth &&
|
if ((pendingMask & GL_STENCIL_BUFFER_BIT) && g.activeHasDepth && (depthAspect & VK_IMAGE_ASPECT_STENCIL_BIT)) {
|
||||||
(depthAspect & VK_IMAGE_ASPECT_STENCIL_BIT)) {
|
|
||||||
effectiveMask |= GL_STENCIL_BUFFER_BIT;
|
effectiveMask |= GL_STENCIL_BUFFER_BIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2917,8 +2674,7 @@ namespace MobileGL::MG_Backend::DirectVulkan::TmpImpl {
|
|||||||
VkClearAttachment color{};
|
VkClearAttachment color{};
|
||||||
color.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
color.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||||
color.colorAttachment = i;
|
color.colorAttachment = i;
|
||||||
color.clearValue.color = {g.clearColor.x(), g.clearColor.y(), g.clearColor.z(),
|
color.clearValue.color = {g.clearColor.x(), g.clearColor.y(), g.clearColor.z(), g.clearColor.w()};
|
||||||
g.clearColor.w()};
|
|
||||||
atts.push_back(color);
|
atts.push_back(color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3051,7 +2807,6 @@ namespace MobileGL::MG_Backend::DirectVulkan::TmpImpl {
|
|||||||
}
|
}
|
||||||
frame.TrashImages.clear();
|
frame.TrashImages.clear();
|
||||||
}
|
}
|
||||||
} // namespace
|
|
||||||
|
|
||||||
void FrameBegin() {
|
void FrameBegin() {
|
||||||
EnsureInitialized();
|
EnsureInitialized();
|
||||||
@@ -3097,6 +2852,11 @@ namespace MobileGL::MG_Backend::DirectVulkan::TmpImpl {
|
|||||||
FrameBeginInternal();
|
FrameBeginInternal();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const VulkanState& GetVulkanState() {
|
||||||
|
EnsureInitialized();
|
||||||
|
return g;
|
||||||
|
}
|
||||||
|
|
||||||
void InitVulkan(ANativeWindow* window) {
|
void InitVulkan(ANativeWindow* window) {
|
||||||
if (g.initialized) return;
|
if (g.initialized) return;
|
||||||
|
|
||||||
|
|||||||
@@ -8,11 +8,229 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <Includes.h>
|
#include <Includes.h>
|
||||||
|
#include "Renderer/VkCommon.h"
|
||||||
|
#include "Renderer/VulkanContext.h"
|
||||||
|
#include "Renderer/SwapchainManager.h"
|
||||||
|
#include "Renderer/FrameContext.h"
|
||||||
|
#include "Managers/ProgramManager.h"
|
||||||
|
#include <MG_State/GLState/Core.h>
|
||||||
|
|
||||||
namespace MobileGL::MG_Backend::DirectVulkan::TmpImpl {
|
namespace MobileGL::MG_Backend::DirectVulkan::TmpImpl {
|
||||||
|
namespace DV = MobileGL::MG_Backend::DirectVulkan::VkManager;
|
||||||
|
using BufferObject = MobileGL::MG_State::GLState::BufferObject;
|
||||||
|
using ProgramObject = MobileGL::MG_State::GLState::ProgramObject;
|
||||||
|
using VertexArrayObject = MobileGL::MG_State::GLState::VertexArrayObject;
|
||||||
|
using FramebufferObject = MobileGL::MG_State::GLState::FramebufferObject;
|
||||||
|
using FramebufferAttachmentObject = MobileGL::MG_State::GLState::FramebufferAttachmentObject;
|
||||||
|
using ITextureObject = MobileGL::MG_State::GLState::ITextureObject;
|
||||||
|
using RenderbufferObject = MobileGL::MG_State::GLState::RenderbufferObject;
|
||||||
|
using SamplerObject = MobileGL::MG_State::GLState::SamplerObject;
|
||||||
|
using TextureObjectMipmap = MobileGL::MG_State::GLState::TextureObjectMipmap;
|
||||||
|
using TrashImage = MobileGL::MG_Backend::DirectVulkan::TrashImage;
|
||||||
|
|
||||||
|
struct BufferResource {
|
||||||
|
VkBuffer buffer = VK_NULL_HANDLE;
|
||||||
|
VkDeviceMemory memory = VK_NULL_HANDLE;
|
||||||
|
VkDeviceSize size = 0;
|
||||||
|
VkBufferUsageFlags usage = 0;
|
||||||
|
VkMemoryPropertyFlags props = 0;
|
||||||
|
void* mapped = nullptr;
|
||||||
|
Uint32 lastUsedFrame = ~0u;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TextureResource {
|
||||||
|
VkImage image = VK_NULL_HANDLE;
|
||||||
|
VkDeviceMemory memory = VK_NULL_HANDLE;
|
||||||
|
VkImageView view = VK_NULL_HANDLE;
|
||||||
|
UnorderedMap<Uint32, VkImageView> mipViews;
|
||||||
|
VkFormat format = VK_FORMAT_UNDEFINED;
|
||||||
|
VkExtent3D extent{0, 0, 1};
|
||||||
|
VkImageLayout layout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||||
|
Uint32 mipLevels = 1;
|
||||||
|
Uint16 paramsVersion = 0;
|
||||||
|
bool valid = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct RenderbufferResource {
|
||||||
|
VkImage image = VK_NULL_HANDLE;
|
||||||
|
VkDeviceMemory memory = VK_NULL_HANDLE;
|
||||||
|
VkImageView view = VK_NULL_HANDLE;
|
||||||
|
VkFormat format = VK_FORMAT_UNDEFINED;
|
||||||
|
VkExtent2D extent{0, 0};
|
||||||
|
VkImageLayout layout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||||
|
bool valid = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SamplerResource {
|
||||||
|
VkSampler sampler = VK_NULL_HANDLE;
|
||||||
|
Uint16 version = 0;
|
||||||
|
SamplerParameters params{};
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PendingClearInfo {
|
||||||
|
GLbitfield mask = 0;
|
||||||
|
FloatVec4 clearColor = {0.0f, 0.0f, 0.0f, 1.0f};
|
||||||
|
Float clearDepth = 1.0f;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct UniformBindingInfo {
|
||||||
|
String name;
|
||||||
|
Uint32 binding = 0;
|
||||||
|
Uint32 set = 0;
|
||||||
|
Uint32 blockIndex = 0xFFFFFFFFu;
|
||||||
|
VkShaderStageFlags stages = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SamplerBindingInfo {
|
||||||
|
String name;
|
||||||
|
Uint32 binding = 0;
|
||||||
|
Uint32 set = 0;
|
||||||
|
VkShaderStageFlags stages = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ProgramResource {
|
||||||
|
ProgramObject* program = nullptr;
|
||||||
|
Uint64 spvHash = 0;
|
||||||
|
DV::ProgramManager::HashType programHash = 0;
|
||||||
|
Vector<VkPipelineShaderStageCreateInfo>* shaderStages = nullptr;
|
||||||
|
|
||||||
|
VkDescriptorSetLayout setLayout = VK_NULL_HANDLE;
|
||||||
|
VkPipelineLayout pipelineLayout = VK_NULL_HANDLE;
|
||||||
|
|
||||||
|
struct UboPool {
|
||||||
|
Vector<BufferResource> buffers;
|
||||||
|
Uint32 cursor = 0;
|
||||||
|
};
|
||||||
|
Vector<UboPool> uboPools;
|
||||||
|
SizeT uboSize = 0;
|
||||||
|
Int32 uboBinding = -1;
|
||||||
|
Uint32 uniformDescriptorCount = 0;
|
||||||
|
Uint32 samplerDescriptorCount = 0;
|
||||||
|
|
||||||
|
Vector<UniformBindingInfo> uniformBindings;
|
||||||
|
Vector<SamplerBindingInfo> samplerBindings;
|
||||||
|
UnorderedMap<String, Uint32> samplerBindingByName;
|
||||||
|
|
||||||
|
UnorderedMap<Uint64, VkPipeline> pipelines;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DescriptorPoolConfig {
|
||||||
|
Uint32 maxSets = 0;
|
||||||
|
Uint32 uniformCount = 0;
|
||||||
|
Uint32 samplerCount = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FrameDescriptorPools {
|
||||||
|
Vector<VkDescriptorPool> pools;
|
||||||
|
DescriptorPoolConfig config;
|
||||||
|
Uint32 activePool = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct VertexAttribKey {
|
||||||
|
Uint8 enabled = 0;
|
||||||
|
Uint8 size = 0;
|
||||||
|
Uint8 type = 0;
|
||||||
|
Uint8 normalized = 0;
|
||||||
|
Uint8 isInteger = 0;
|
||||||
|
Uint8 divisor = 0;
|
||||||
|
Uint16 pad = 0;
|
||||||
|
Uint32 stride = 0;
|
||||||
|
Uint64 offset = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct AttachmentInfo {
|
||||||
|
FramebufferAttachmentType type = FramebufferAttachmentType::None;
|
||||||
|
VkImageView view = VK_NULL_HANDLE;
|
||||||
|
VkFormat format = VK_FORMAT_UNDEFINED;
|
||||||
|
VkImageAspectFlags aspect = 0;
|
||||||
|
VkImageLayout finalLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||||
|
ITextureObject* texture = nullptr;
|
||||||
|
RenderbufferObject* renderbuffer = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BackendFramebufferObject {
|
||||||
|
Array<VkRenderPass, 8> renderPasses = {};
|
||||||
|
VkFramebuffer framebuffer = VK_NULL_HANDLE;
|
||||||
|
VkExtent2D extent{0, 0};
|
||||||
|
Uint32 colorAttachmentCount = 0;
|
||||||
|
Bool hasDepth = false;
|
||||||
|
VkFormat depthFormat = VK_FORMAT_UNDEFINED;
|
||||||
|
Uint64 renderPassCompatHash = 0;
|
||||||
|
|
||||||
|
Vector<AttachmentInfo> attachments;
|
||||||
|
Array<Int32, static_cast<SizeT>(FramebufferAttachmentType::FramebufferAttachmentTypeCount)> attachmentIndex =
|
||||||
|
{};
|
||||||
|
|
||||||
|
FramebufferObject::FramebufferAttachmentVersionArray syncedAttachmentVersions = {0};
|
||||||
|
FramebufferObject::FramebufferAttachmentArray frontendDrawBuffers = {FramebufferAttachmentType::None};
|
||||||
|
Array<Int32, FramebufferObject::MAX_DRAW_BUFFERS> drawBufferAttachmentIndices = {};
|
||||||
|
FramebufferAttachmentType frontendReadBuffer = FramebufferAttachmentType::Color0;
|
||||||
|
Uint64 configHash = 0;
|
||||||
|
Uint16 objectVersion = 0;
|
||||||
|
|
||||||
|
Bool IsValid() const { return renderPasses[0] != VK_NULL_HANDLE && framebuffer != VK_NULL_HANDLE; }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct VulkanState {
|
||||||
|
UniquePtr<DV::VulkanContext> ctx;
|
||||||
|
UniquePtr<DV::SwapchainManager> swapchain;
|
||||||
|
UniquePtr<DV::ProgramManager> programMgr;
|
||||||
|
Array<VkRenderPass, 8> renderPasses = {};
|
||||||
|
VkCommandPool commandPool = VK_NULL_HANDLE;
|
||||||
|
Vector<UniquePtr<DV::FrameContext>> frames;
|
||||||
|
Vector<FrameDescriptorPools> frameDescriptorPools;
|
||||||
|
Uint32 currentFrame = 0;
|
||||||
|
Uint32 maxFramesInFlight = 2;
|
||||||
|
Bool initialized = false;
|
||||||
|
UintVec2 viewportSize{0, 0};
|
||||||
|
|
||||||
|
VkImage depthImage = VK_NULL_HANDLE;
|
||||||
|
VkDeviceMemory depthMemory = VK_NULL_HANDLE;
|
||||||
|
VkImageView depthView = VK_NULL_HANDLE;
|
||||||
|
VkFormat depthFormat = VK_FORMAT_UNDEFINED;
|
||||||
|
Uint64 defaultRenderPassCompatHash = 0;
|
||||||
|
|
||||||
|
BufferResource nullUbo;
|
||||||
|
|
||||||
|
TextureResource defaultTexture;
|
||||||
|
SamplerResource defaultSampler;
|
||||||
|
|
||||||
|
UnorderedMap<const BufferObject*, BufferResource> buffers;
|
||||||
|
UnorderedMap<const ITextureObject*, TextureResource> textures;
|
||||||
|
UnorderedMap<const RenderbufferObject*, RenderbufferResource> renderbuffers;
|
||||||
|
UnorderedMap<const SamplerObject*, SamplerResource> samplers;
|
||||||
|
UnorderedMap<const ProgramObject*, ProgramResource> programs;
|
||||||
|
UnorderedMap<SharedPtr<MG_State::GLState::FramebufferObject>, SharedPtr<BackendFramebufferObject>> framebuffers;
|
||||||
|
|
||||||
|
VkRenderPass activeRenderPass = VK_NULL_HANDLE;
|
||||||
|
VkFramebuffer activeFramebuffer = VK_NULL_HANDLE;
|
||||||
|
VkExtent2D activeExtent{0, 0};
|
||||||
|
Uint32 activeColorAttachmentCount = 1;
|
||||||
|
Bool activeHasDepth = false;
|
||||||
|
VkFormat activeDepthFormat = VK_FORMAT_UNDEFINED;
|
||||||
|
SharedPtr<MG_State::GLState::FramebufferObject> activeStateFBO = nullptr;
|
||||||
|
SharedPtr<BackendFramebufferObject> activeBackendFBO = nullptr;
|
||||||
|
Bool activeIsDefault = true;
|
||||||
|
Bool activeDefaultColorWrites = true;
|
||||||
|
|
||||||
|
VkRenderPass recordingRenderPass = VK_NULL_HANDLE;
|
||||||
|
VkFramebuffer recordingFramebuffer = VK_NULL_HANDLE;
|
||||||
|
Bool cmdBufferBegun = false;
|
||||||
|
|
||||||
|
Bool recording = false;
|
||||||
|
Bool frameSubmitted = false;
|
||||||
|
FloatVec4 clearColor = {0.0f, 0.0f, 0.0f, 1.0f};
|
||||||
|
Float clearDepth = 1.0f;
|
||||||
|
|
||||||
|
UnorderedMap<SharedPtr<FramebufferObject>, PendingClearInfo> pendingClears;
|
||||||
|
|
||||||
|
Vector<VkImageLayout> swapchainImageLayouts;
|
||||||
|
};
|
||||||
|
|
||||||
void Present();
|
void Present();
|
||||||
void FrameBegin();
|
void FrameBegin();
|
||||||
void InitVulkan(ANativeWindow* window);
|
void InitVulkan(ANativeWindow* window);
|
||||||
|
const VulkanState& GetVulkanState();
|
||||||
void ClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);
|
void ClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);
|
||||||
void ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat* value);
|
void ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat* value);
|
||||||
void ClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint* value);
|
void ClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint* value);
|
||||||
@@ -49,5 +267,4 @@ namespace MobileGL::MG_Backend::DirectVulkan::TmpImpl {
|
|||||||
void CopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width,
|
void CopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width,
|
||||||
GLsizei height);
|
GLsizei height);
|
||||||
void GenerateMipmap(GLenum target);
|
void GenerateMipmap(GLenum target);
|
||||||
void Present();
|
|
||||||
} // namespace MobileGL::MG_Backend::DirectVulkan::TmpImpl
|
} // namespace MobileGL::MG_Backend::DirectVulkan::TmpImpl
|
||||||
@@ -7,8 +7,6 @@
|
|||||||
// End of Source File Header
|
// End of Source File Header
|
||||||
|
|
||||||
#include "GL_Getter.h"
|
#include "GL_Getter.h"
|
||||||
#include "GL/gl.h"
|
|
||||||
#include "MG_Util/Debug/Log.h"
|
|
||||||
#include <Config.h>
|
#include <Config.h>
|
||||||
#include <MGGitHash.h>
|
#include <MGGitHash.h>
|
||||||
#include <MG_State/GLState/Core.h>
|
#include <MG_State/GLState/Core.h>
|
||||||
|
|||||||
@@ -31,8 +31,9 @@ namespace MobileGL {
|
|||||||
// Compile for OpenGL here, so that we can do validation and link
|
// Compile for OpenGL here, so that we can do validation and link
|
||||||
// like a real OpenGL driver at linking stage
|
// like a real OpenGL driver at linking stage
|
||||||
// Will compile for other backends later.
|
// Will compile for other backends later.
|
||||||
ShaderAttrib attrib{
|
ShaderAttrib attrib{.shaderType = MG_Util::ConvertShaderStageToGLEnum(m_stage),
|
||||||
.shaderType = MG_Util::ConvertShaderStageToGLEnum(m_stage), .sourceStr = m_source, .flags = ShaderCompileBits::CompileForOpenGL};
|
.sourceStr = m_source,
|
||||||
|
.flags = ShaderCompileBits::CompileForOpenGL};
|
||||||
|
|
||||||
auto result = ShaderCompiler::CompileShader(attrib);
|
auto result = ShaderCompiler::CompileShader(attrib);
|
||||||
if (result) {
|
if (result) {
|
||||||
|
|||||||
@@ -0,0 +1,51 @@
|
|||||||
|
// 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;
|
||||||
|
}
|
||||||
|
} // namespace MobileGL::MG_Util::BackendLoader
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
// 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);
|
||||||
|
} // namespace MG_Util::BackendLoader
|
||||||
|
} // namespace MobileGL
|
||||||
Reference in New Issue
Block a user