mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-11 21:58:31 +09:00
[Feat] (MG_Backend/DirectVulkan): ProgramFactory and some refactoring
This commit is contained in:
+3
-5
@@ -211,9 +211,7 @@ set(SOURCE_FILES
|
|||||||
MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.cpp
|
MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.cpp
|
||||||
MobileGL/MG_Backend/DirectVulkan/Renderer/SwapchainObject.cpp
|
MobileGL/MG_Backend/DirectVulkan/Renderer/SwapchainObject.cpp
|
||||||
MobileGL/MG_Backend/DirectVulkan/Renderer/FrameContext.cpp
|
MobileGL/MG_Backend/DirectVulkan/Renderer/FrameContext.cpp
|
||||||
# MobileGL/MG_Backend/DirectVulkan/Managers/ProgramManager.cpp
|
MobileGL/MG_Backend/DirectVulkan/Renderer/ProgramFactory.cpp
|
||||||
# MobileGL/MG_Backend/DirectVulkan/Managers/VertexInputStateManager.cpp
|
|
||||||
# MobileGL/MG_Backend/DirectVulkan/Managers/RenderStateManager.cpp
|
|
||||||
|
|
||||||
MobileGL/MG_State/GLState/Core.cpp
|
MobileGL/MG_State/GLState/Core.cpp
|
||||||
MobileGL/MG_State/GLState/ErrorState/Error.cpp
|
MobileGL/MG_State/GLState/ErrorState/Error.cpp
|
||||||
@@ -282,7 +280,7 @@ target_include_directories(${CMAKE_PROJECT_NAME} PUBLIC
|
|||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(${CMAKE_PROJECT_NAME}
|
target_link_libraries(${CMAKE_PROJECT_NAME}
|
||||||
PRIVATE
|
PUBLIC
|
||||||
${MOBILEGL_LINK_LIBRARIES}
|
${MOBILEGL_LINK_LIBRARIES}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -310,7 +308,7 @@ if(NOT ANDROID)
|
|||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(${CMAKE_PROJECT_NAME}_s
|
target_link_libraries(${CMAKE_PROJECT_NAME}_s
|
||||||
PRIVATE
|
PUBLIC
|
||||||
${MOBILEGL_LINK_LIBRARIES}
|
${MOBILEGL_LINK_LIBRARIES}
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
@@ -50,6 +50,9 @@
|
|||||||
// Include FastSTL
|
// Include FastSTL
|
||||||
#include <FastSTL/UnorderedMap.h>
|
#include <FastSTL/UnorderedMap.h>
|
||||||
|
|
||||||
|
// Include xxHash
|
||||||
|
#include <xxhash.h>
|
||||||
|
|
||||||
// Include spirv_cross
|
// Include spirv_cross
|
||||||
#include <spirv_cross/spirv_cross_c.h>
|
#include <spirv_cross/spirv_cross_c.h>
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,86 @@
|
|||||||
|
// MobileGL - MobileGL/MG_Backend/DirectVulkan/Renderer/ProgramFactory.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 "ProgramFactory.h"
|
||||||
|
|
||||||
|
namespace MobileGL::MG_Backend::DirectVulkan {
|
||||||
|
ProgramFactory::~ProgramFactory() {}
|
||||||
|
|
||||||
|
VkShaderStageFlagBits ProgramFactory::ToVkStage(ShaderStage stage) {
|
||||||
|
switch (stage) {
|
||||||
|
case ShaderStage::Vertex:
|
||||||
|
return VK_SHADER_STAGE_VERTEX_BIT;
|
||||||
|
case ShaderStage::Fragment:
|
||||||
|
return VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||||
|
case ShaderStage::Geometry:
|
||||||
|
return VK_SHADER_STAGE_GEOMETRY_BIT;
|
||||||
|
case ShaderStage::TessControl:
|
||||||
|
return VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT;
|
||||||
|
case ShaderStage::TessEval:
|
||||||
|
return VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT;
|
||||||
|
case ShaderStage::Compute:
|
||||||
|
return VK_SHADER_STAGE_COMPUTE_BIT;
|
||||||
|
default:
|
||||||
|
return VK_SHADER_STAGE_ALL_GRAPHICS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ProgramFactory::HashType ProgramFactory::ComputeHash(const MG_State::GLState::ProgramObject& program,
|
||||||
|
CompileOptionFlags flags) const {
|
||||||
|
XXHASH_VERIFY(XXH64_reset(m_hashState, m_config.CacheVersion));
|
||||||
|
// We expect shader stages in program object are sorted
|
||||||
|
const auto& spirvs = program.GetGeneratedSpirv();
|
||||||
|
for (const auto& spv : spirvs) {
|
||||||
|
XXHASH_VERIFY(XXH64_update(m_hashState, spv.data(), spv.size() * sizeof(Uint)));
|
||||||
|
}
|
||||||
|
XXHASH_VERIFY(XXH64_update(m_hashState, &flags, sizeof(CompileOptionFlags)));
|
||||||
|
HashType hash = XXH64_digest(m_hashState);
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector<VkPipelineShaderStageCreateInfo>& ProgramFactory::GetOrCreatePipelineShaderStages(
|
||||||
|
const MG_State::GLState::ProgramObject& program, CompileOptionFlags flags) {
|
||||||
|
auto hash = ComputeHash(program, flags);
|
||||||
|
auto it = m_cache.find(hash);
|
||||||
|
if (it != m_cache.end()) {
|
||||||
|
return it->second.stages;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto& entry = m_cache[hash];
|
||||||
|
entry.device = m_device;
|
||||||
|
entry.hash = hash;
|
||||||
|
auto& shaders = program.GetAttachedShaders();
|
||||||
|
auto& spirv = program.GetGeneratedSpirv();
|
||||||
|
|
||||||
|
for (SizeT i = 0; i < shaders.size(); ++i) {
|
||||||
|
auto& spv = spirv[i];
|
||||||
|
if (spv.empty())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// TODO: Do SPIR-V postprocessing here
|
||||||
|
|
||||||
|
VkShaderModuleCreateInfo smci{VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO};
|
||||||
|
smci.codeSize = spv.size() * sizeof(Uint);
|
||||||
|
smci.pCode = spv.data();
|
||||||
|
|
||||||
|
VkShaderModule module = VK_NULL_HANDLE;
|
||||||
|
VK_VERIFY(vkCreateShaderModule(m_device, &smci, nullptr, &module), "vkCreateShaderModule");
|
||||||
|
|
||||||
|
VkPipelineShaderStageCreateInfo stage{VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO};
|
||||||
|
ShaderStage shaderStage = shaders[i]->GetShaderStage();
|
||||||
|
stage.stage = ToVkStage(shaderStage);
|
||||||
|
stage.module = module;
|
||||||
|
stage.pName = "main";
|
||||||
|
|
||||||
|
entry.modules.push_back(module);
|
||||||
|
entry.stages.push_back(stage);
|
||||||
|
}
|
||||||
|
|
||||||
|
return entry.stages;
|
||||||
|
}
|
||||||
|
} // namespace MobileGL::MG_Backend::DirectVulkan
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
// MobileGL - MobileGL/MG_Backend/DirectVulkan/Renderer/ProgramFactory.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 "../VkIncludes.h"
|
||||||
|
#include "MG_State/GLState/ProgramState/ProgramObject.h"
|
||||||
|
#include "MG_State/GLState/ProgramState/ShaderObject.h"
|
||||||
|
#include <Includes.h>
|
||||||
|
|
||||||
|
namespace MobileGL::MG_Backend::DirectVulkan {
|
||||||
|
class ProgramFactory {
|
||||||
|
public:
|
||||||
|
enum class CompileOptionBit : Uint {
|
||||||
|
None = 0,
|
||||||
|
PositionYFlip = 1 << 0,
|
||||||
|
PositionZRemap = 1 << 1,
|
||||||
|
};
|
||||||
|
using CompileOptionFlags = Flags<CompileOptionBit>;
|
||||||
|
using HashType = Uint64;
|
||||||
|
struct BackendProgramObject {
|
||||||
|
HashType hash = 0;
|
||||||
|
VkDevice device = VK_NULL_HANDLE;
|
||||||
|
Vector<VkPipelineShaderStageCreateInfo> stages;
|
||||||
|
Vector<VkShaderModule> modules;
|
||||||
|
|
||||||
|
~BackendProgramObject() {
|
||||||
|
for (auto module: modules) {
|
||||||
|
vkDestroyShaderModule(device, module, nullptr);
|
||||||
|
}
|
||||||
|
modules.clear();
|
||||||
|
stages.clear();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
explicit ProgramFactory(VkDevice device, const VulkanRendererConfig& config):
|
||||||
|
m_device(device), m_config(config) {}
|
||||||
|
~ProgramFactory();
|
||||||
|
ProgramFactory(const ProgramFactory&) = delete;
|
||||||
|
|
||||||
|
HashType ComputeHash(const MG_State::GLState::ProgramObject& program, CompileOptionFlags flags) const;
|
||||||
|
Vector<VkPipelineShaderStageCreateInfo>& GetOrCreatePipelineShaderStages(const MG_State::GLState::ProgramObject& program, CompileOptionFlags flags);
|
||||||
|
|
||||||
|
static VkShaderStageFlagBits ToVkStage(ShaderStage stage);
|
||||||
|
private:
|
||||||
|
VkDevice m_device = VK_NULL_HANDLE;
|
||||||
|
UnorderedMap<HashType, BackendProgramObject> m_cache;
|
||||||
|
const VulkanRendererConfig& m_config;
|
||||||
|
static inline XXH64_state_t* m_hashState = XXH64_createState();
|
||||||
|
};
|
||||||
|
} // namespace MobileGL::MG_Backend::DirectVulkan
|
||||||
@@ -48,7 +48,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
return VK_FALSE;
|
return VK_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
VulkanRenderer::VulkanRenderer(NativeWindowType window, const RendererConfig& cfg)
|
VulkanRenderer::VulkanRenderer(NativeWindowType window, const VulkanRendererConfig& cfg)
|
||||||
: m_window(window), m_config(cfg) {
|
: m_window(window), m_config(cfg) {
|
||||||
// Initialize();
|
// Initialize();
|
||||||
}
|
}
|
||||||
@@ -100,41 +100,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector<Uint> vsSpv;
|
auto& stages = m_programFactory->GetOrCreatePipelineShaderStages(programObject, ProgramFactory::CompileOptionBit::None);
|
||||||
Vector<Uint> fsSpv;
|
|
||||||
|
|
||||||
auto& shaderSpirvs = programObject.GetGeneratedSpirv();
|
|
||||||
auto& attachedShaders = programObject.GetAttachedShaders();
|
|
||||||
for (int index = 0; index < attachedShaders.size(); ++index) {
|
|
||||||
auto& shader = attachedShaders[index];
|
|
||||||
auto& spirvCode = shaderSpirvs[index];
|
|
||||||
if (shader->GetShaderStage() == ShaderStage::Vertex) {
|
|
||||||
vsSpv = spirvCode;
|
|
||||||
} else if (shader->GetShaderStage() == ShaderStage::Fragment) {
|
|
||||||
fsSpv = spirvCode;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
VkShaderModuleCreateInfo smci{VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO};
|
|
||||||
smci.codeSize = vsSpv.size() * sizeof(uint32_t);
|
|
||||||
smci.pCode = vsSpv.data();
|
|
||||||
VkShaderModule vs;
|
|
||||||
VK_VERIFY(vkCreateShaderModule(m_device, &smci, nullptr, &vs), "vkCreateShaderModule VS");
|
|
||||||
|
|
||||||
smci.codeSize = fsSpv.size() * sizeof(uint32_t);
|
|
||||||
smci.pCode = fsSpv.data();
|
|
||||||
VkShaderModule fs;
|
|
||||||
VK_VERIFY(vkCreateShaderModule(m_device, &smci, nullptr, &fs), "vkCreateShaderModule FS");
|
|
||||||
|
|
||||||
VkPipelineShaderStageCreateInfo stages[2]{};
|
|
||||||
stages[0] = {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO};
|
|
||||||
stages[0].stage = VK_SHADER_STAGE_VERTEX_BIT;
|
|
||||||
stages[0].module = vs;
|
|
||||||
stages[0].pName = "main";
|
|
||||||
stages[1] = {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO};
|
|
||||||
stages[1].stage = VK_SHADER_STAGE_FRAGMENT_BIT;
|
|
||||||
stages[1].module = fs;
|
|
||||||
stages[1].pName = "main";
|
|
||||||
|
|
||||||
VkPipelineLayoutCreateInfo plci{VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO};
|
VkPipelineLayoutCreateInfo plci{VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO};
|
||||||
VK_VERIFY(vkCreatePipelineLayout(m_device, &plci, nullptr, &m_pipelineLayout), "vkCreatePipelineLayout");
|
VK_VERIFY(vkCreatePipelineLayout(m_device, &plci, nullptr, &m_pipelineLayout), "vkCreatePipelineLayout");
|
||||||
@@ -188,7 +154,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
// Create Pipeline
|
// Create Pipeline
|
||||||
VkGraphicsPipelineCreateInfo gpi{VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO};
|
VkGraphicsPipelineCreateInfo gpi{VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO};
|
||||||
gpi.stageCount = 2;
|
gpi.stageCount = 2;
|
||||||
gpi.pStages = stages;
|
gpi.pStages = stages.data();
|
||||||
gpi.pVertexInputState = &vertexInput;
|
gpi.pVertexInputState = &vertexInput;
|
||||||
gpi.pInputAssemblyState = &ia;
|
gpi.pInputAssemblyState = &ia;
|
||||||
gpi.pViewportState = &vpci;
|
gpi.pViewportState = &vpci;
|
||||||
@@ -203,8 +169,8 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
VK_VERIFY(vkCreateGraphicsPipelines(m_device, VK_NULL_HANDLE, 1, &gpi, nullptr, &m_pipeline),
|
VK_VERIFY(vkCreateGraphicsPipelines(m_device, VK_NULL_HANDLE, 1, &gpi, nullptr, &m_pipeline),
|
||||||
"vkCreateGraphicsPipelines");
|
"vkCreateGraphicsPipelines");
|
||||||
|
|
||||||
vkDestroyShaderModule(m_device, vs, nullptr);
|
// vkDestroyShaderModule(m_device, vs, nullptr);
|
||||||
vkDestroyShaderModule(m_device, fs, nullptr);
|
// vkDestroyShaderModule(m_device, fs, nullptr);
|
||||||
|
|
||||||
MGLOG_I("PrepareDemoPipeline completed");
|
MGLOG_I("PrepareDemoPipeline completed");
|
||||||
}
|
}
|
||||||
@@ -225,6 +191,8 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
|
|
||||||
RecreateSwapchain();
|
RecreateSwapchain();
|
||||||
|
|
||||||
|
m_programFactory = MakeUnique<ProgramFactory>(m_device, m_config);
|
||||||
|
|
||||||
PrepareDemoPipeline();
|
PrepareDemoPipeline();
|
||||||
CreateFrameContexts();
|
CreateFrameContexts();
|
||||||
|
|
||||||
@@ -241,6 +209,8 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
void VulkanRenderer::Shutdown() {
|
void VulkanRenderer::Shutdown() {
|
||||||
VK_VERIFY(vkDeviceWaitIdle(m_device));
|
VK_VERIFY(vkDeviceWaitIdle(m_device));
|
||||||
|
|
||||||
|
m_programFactory.reset();
|
||||||
|
|
||||||
m_frameContext.Destroy(m_device, m_commandPool);
|
m_frameContext.Destroy(m_device, m_commandPool);
|
||||||
|
|
||||||
if (m_pipeline != VK_NULL_HANDLE) {
|
if (m_pipeline != VK_NULL_HANDLE) {
|
||||||
|
|||||||
@@ -9,25 +9,16 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "Config.h"
|
#include "Config.h"
|
||||||
#include "FrameContext.h"
|
#include "FrameContext.h"
|
||||||
|
#include "ProgramFactory.h"
|
||||||
#include "SwapchainObject.h"
|
#include "SwapchainObject.h"
|
||||||
#include <Includes.h>
|
#include <Includes.h>
|
||||||
|
|
||||||
#include "../VkIncludes.h"
|
#include "../VkIncludes.h"
|
||||||
|
|
||||||
namespace MobileGL::MG_Backend::DirectVulkan {
|
namespace MobileGL::MG_Backend::DirectVulkan {
|
||||||
using RenderCallback = std::function<void(VkCommandBuffer cmdBuf, uint32_t imageIndex, VkExtent2D extent)>;
|
|
||||||
|
|
||||||
struct RendererConfig {
|
|
||||||
Uint32 MaxFramesInFlight = 2;
|
|
||||||
String AppName = "MobileGL-VulkanRenderer";
|
|
||||||
Version Version = MG_Config::CoreVersion;
|
|
||||||
Uint64 CacheVersion = MG_Config::CacheVersion;
|
|
||||||
Bool EnableValidationLayers = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
class VulkanRenderer {
|
class VulkanRenderer {
|
||||||
public:
|
public:
|
||||||
VulkanRenderer(NativeWindowType window, const RendererConfig& cfg = {});
|
VulkanRenderer(NativeWindowType window, const VulkanRendererConfig& cfg = {});
|
||||||
~VulkanRenderer();
|
~VulkanRenderer();
|
||||||
|
|
||||||
void Initialize();
|
void Initialize();
|
||||||
@@ -57,7 +48,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
};
|
};
|
||||||
|
|
||||||
NativeWindowType m_window = 0;
|
NativeWindowType m_window = 0;
|
||||||
RendererConfig m_config;
|
VulkanRendererConfig m_config;
|
||||||
|
|
||||||
// Vulkan objects
|
// Vulkan objects
|
||||||
Bool m_validationLayersEnabled = false;
|
Bool m_validationLayersEnabled = false;
|
||||||
@@ -87,6 +78,8 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
Uint m_imageIndexAcquired = 0;
|
Uint m_imageIndexAcquired = 0;
|
||||||
FrameContext m_frameContext;
|
FrameContext m_frameContext;
|
||||||
|
|
||||||
|
UniquePtr<ProgramFactory> m_programFactory;
|
||||||
|
|
||||||
void CreateInstance();
|
void CreateInstance();
|
||||||
VkResult SetupDebugMessenger();
|
VkResult SetupDebugMessenger();
|
||||||
VkResult DestroyDebugMessenger();
|
VkResult DestroyDebugMessenger();
|
||||||
|
|||||||
@@ -8,6 +8,8 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "VulkanRendererConfig.h"
|
||||||
|
|
||||||
#define VK_VERIFY(expr, ...) \
|
#define VK_VERIFY(expr, ...) \
|
||||||
do { \
|
do { \
|
||||||
VkResult _vk_verify_result = (expr); \
|
VkResult _vk_verify_result = (expr); \
|
||||||
@@ -15,3 +17,9 @@
|
|||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define ENUM_STR_CASE(c) case c: return #c;
|
#define ENUM_STR_CASE(c) case c: return #c;
|
||||||
|
|
||||||
|
#define XXHASH_VERIFY(expr, ...) \
|
||||||
|
do { \
|
||||||
|
XXH_errorcode _xxh_verify_result = (expr); \
|
||||||
|
MOBILEGL_ASSERT(_xxh_verify_result == XXH_OK, "XXHash error %d at %s:%d" __VA_OPT__(" - ") __VA_ARGS__, _xxh_verify_result, __FILE__, __LINE__); \
|
||||||
|
} while (0)
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
// MobileGL - MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRendererConfig.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 "Config.h"
|
||||||
|
|
||||||
|
namespace MobileGL::MG_Backend::DirectVulkan {
|
||||||
|
struct VulkanRendererConfig {
|
||||||
|
Uint32 MaxFramesInFlight = 2;
|
||||||
|
String AppName = "MobileGL-VulkanRenderer";
|
||||||
|
Version Version = MG_Config::CoreVersion;
|
||||||
|
Uint64 CacheVersion = MG_Config::CacheVersion;
|
||||||
|
Bool EnableValidationLayers = true;
|
||||||
|
};
|
||||||
|
} // namespace MobileGL::MG_Backend::DirectVulkan
|
||||||
@@ -179,6 +179,10 @@ namespace MobileGL {
|
|||||||
return m_shaders;
|
return m_shaders;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Vector<SharedPtr<ShaderObject>>& ProgramObject::GetAttachedShaders() const {
|
||||||
|
return m_shaders;
|
||||||
|
}
|
||||||
|
|
||||||
void ProgramObject::DoReflection() {
|
void ProgramObject::DoReflection() {
|
||||||
if (!m_program) {
|
if (!m_program) {
|
||||||
MGLOG_E("ProgramObject %u: DoReflection called but m_program is null", m_externalIndex);
|
MGLOG_E("ProgramObject %u: DoReflection called but m_program is null", m_externalIndex);
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ namespace MobileGL {
|
|||||||
Int GetFragmentDataLocation(const char* name);
|
Int GetFragmentDataLocation(const char* name);
|
||||||
|
|
||||||
Vector<SharedPtr<ShaderObject>>& GetAttachedShaders();
|
Vector<SharedPtr<ShaderObject>>& GetAttachedShaders();
|
||||||
|
const Vector<SharedPtr<ShaderObject>>& GetAttachedShaders() const;
|
||||||
const String& GetInfoLog() const { return m_infoLog; }
|
const String& GetInfoLog() const { return m_infoLog; }
|
||||||
Int GetUniformMaxLength() const { return m_uniformNameMaxLength; }
|
Int GetUniformMaxLength() const { return m_uniformNameMaxLength; }
|
||||||
Uint GetUniformCount() { return m_activeUniformCount; }
|
Uint GetUniformCount() { return m_activeUniformCount; }
|
||||||
@@ -111,6 +112,7 @@ namespace MobileGL {
|
|||||||
Uint GetUniformBlockBinding(Uint index) const { return m_uniformBlockBinding[index]; }
|
Uint GetUniformBlockBinding(Uint index) const { return m_uniformBlockBinding[index]; }
|
||||||
|
|
||||||
Vector<Vector<unsigned>>& GetGeneratedSpirv() { return m_generatedSpirv; }
|
Vector<Vector<unsigned>>& GetGeneratedSpirv() { return m_generatedSpirv; }
|
||||||
|
const Vector<Vector<unsigned>>& GetGeneratedSpirv() const { return m_generatedSpirv; }
|
||||||
|
|
||||||
Int GetShaderIndexByStage(ShaderStage stage) const {
|
Int GetShaderIndexByStage(ShaderStage stage) const {
|
||||||
auto it = std::find_if(m_shaders.begin(), m_shaders.end(),
|
auto it = std::find_if(m_shaders.begin(), m_shaders.end(),
|
||||||
|
|||||||
Reference in New Issue
Block a user