mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-08 04:08:32 +09:00
[Chore] (MG_Test/Backend/DirectVulkan): get rid of some junk
This commit is contained in:
@@ -1,133 +0,0 @@
|
||||
// MobileGL - MobileGL/MG_Backend/DirectVulkan/Managers/ProgramManager.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 "ProgramManager.h"
|
||||
|
||||
namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
ProgramManager::ProgramManager(VulkanContext &ctx): m_ctx(ctx) {}
|
||||
|
||||
ProgramManager::~ProgramManager() {
|
||||
Cleanup();
|
||||
}
|
||||
|
||||
void ProgramManager::Cleanup() {
|
||||
auto device = m_ctx.GetDevice();
|
||||
if (device != VK_NULL_HANDLE) {
|
||||
for (auto& [_, stages] : m_shaderStageCreateInfo) {
|
||||
for (auto& stageInfo : stages) {
|
||||
if (stageInfo.module != VK_NULL_HANDLE) {
|
||||
vkDestroyShaderModule(device, stageInfo.module, nullptr);
|
||||
stageInfo.module = VK_NULL_HANDLE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
m_shaderStageCreateInfo.clear();
|
||||
XXH64_freeState(m_hashState);
|
||||
}
|
||||
|
||||
Vector<VkPipelineShaderStageCreateInfo>& ProgramManager::CreatePipelineShaderStages(ProgramObject* programObject) {
|
||||
auto hash = GetHash(programObject);
|
||||
MOBILEGL_ASSERT(m_shaderStageCreateInfo.find(hash) == m_shaderStageCreateInfo.end(),
|
||||
"A program with the same hash has already been created");
|
||||
Vector<VkPipelineShaderStageCreateInfo> info;
|
||||
auto& shaders = programObject->GetAttachedShaders();
|
||||
auto& spirvBinaries = programObject->GetGeneratedSpirv();
|
||||
MOBILEGL_ASSERT(shaders.size() == spirvBinaries.size(),
|
||||
"Shader and SPIR-V binary count mismatch");
|
||||
|
||||
info.reserve(shaders.size());
|
||||
|
||||
auto device = m_ctx.GetDevice();
|
||||
MOBILEGL_ASSERT(device != VK_NULL_HANDLE, "Vulkan device is null");
|
||||
|
||||
for (SizeT i = 0; i < shaders.size(); ++i) {
|
||||
auto shaderStage = shaders[i]->GetShaderStage();
|
||||
VkShaderStageFlagBits vkStage = VK_SHADER_STAGE_FLAG_BITS_MAX_ENUM;
|
||||
switch (shaderStage) {
|
||||
case ShaderStage::Vertex:
|
||||
vkStage = VK_SHADER_STAGE_VERTEX_BIT;
|
||||
break;
|
||||
case ShaderStage::TessControl:
|
||||
vkStage = VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT;
|
||||
break;
|
||||
case ShaderStage::TessEval:
|
||||
vkStage = VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT;
|
||||
break;
|
||||
case ShaderStage::Geometry:
|
||||
vkStage = VK_SHADER_STAGE_GEOMETRY_BIT;
|
||||
break;
|
||||
case ShaderStage::Fragment:
|
||||
vkStage = VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||
break;
|
||||
case ShaderStage::Compute:
|
||||
vkStage = VK_SHADER_STAGE_COMPUTE_BIT;
|
||||
break;
|
||||
default:
|
||||
MOBILEGL_ASSERT(false, "Unsupported shader stage");
|
||||
break;
|
||||
}
|
||||
|
||||
auto& spirv = spirvBinaries[i];
|
||||
MOBILEGL_ASSERT(!spirv.empty(), "SPIR-V binary is empty");
|
||||
VkShaderModuleCreateInfo smci{VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO};
|
||||
smci.codeSize = spirv.size() * sizeof(Uint);
|
||||
smci.pCode = reinterpret_cast<const uint32_t*>(spirv.data());
|
||||
|
||||
VkShaderModule shaderModule = VK_NULL_HANDLE;
|
||||
VK_VERIFY(vkCreateShaderModule(device, &smci, nullptr, &shaderModule), "vkCreateShaderModule");
|
||||
MOBILEGL_ASSERT(shaderModule != VK_NULL_HANDLE, "Failed to create shader module");
|
||||
|
||||
VkPipelineShaderStageCreateInfo stageInfo{VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO};
|
||||
stageInfo.stage = vkStage;
|
||||
stageInfo.module = shaderModule;
|
||||
stageInfo.pName = "main";
|
||||
info.emplace_back(stageInfo);
|
||||
}
|
||||
|
||||
auto [it, inserted] = m_shaderStageCreateInfo.emplace(hash, Move(info));
|
||||
MOBILEGL_ASSERT(inserted, "Failed to cache shader stage create info");
|
||||
return it->second;
|
||||
}
|
||||
|
||||
Vector<VkPipelineShaderStageCreateInfo>* ProgramManager::GetPipelineShaderStages(HashType hash) {
|
||||
auto it = m_shaderStageCreateInfo.find(hash);
|
||||
if (it == m_shaderStageCreateInfo.end()) return nullptr;
|
||||
return &it->second;
|
||||
}
|
||||
|
||||
Vector<VkPipelineShaderStageCreateInfo>* ProgramManager::GetPipelineShaderStages(ProgramObject* programObject) {
|
||||
return GetPipelineShaderStages(GetHash(programObject));
|
||||
}
|
||||
|
||||
ProgramManager::HashType ProgramManager::GetHash(ProgramObject *programObject) {
|
||||
MOBILEGL_ASSERT(programObject && programObject->GetLinkStatus(), "program object is null or not successfully linked!");
|
||||
MOBILEGL_ASSERT(m_hashState != nullptr, "Hash state should already be initialized");
|
||||
|
||||
XXH64_hash_t const seed = MG_Config::CacheVersion;
|
||||
auto errc = XXH64_reset(m_hashState, seed);
|
||||
MOBILEGL_ASSERT(errc == XXH_OK, "Hash state reset failed");
|
||||
|
||||
auto& shaders = programObject->GetAttachedShaders();
|
||||
auto& spirvBinaries = programObject->GetGeneratedSpirv();
|
||||
auto count = shaders.size();
|
||||
|
||||
for (auto i = 0; i < count; i++) {
|
||||
auto& shader = shaders[i];
|
||||
auto stage = shader->GetShaderStage();
|
||||
errc = XXH64_update(m_hashState, &stage, sizeof(stage));
|
||||
MOBILEGL_ASSERT(errc == XXH_OK, "Hash state update failed");
|
||||
errc = XXH64_update(m_hashState, spirvBinaries[i].data(), spirvBinaries[i].size() * sizeof(unsigned));
|
||||
MOBILEGL_ASSERT(errc == XXH_OK, "Hash state update failed");
|
||||
}
|
||||
|
||||
HashType hash = XXH64_digest(m_hashState);
|
||||
|
||||
return hash;
|
||||
}
|
||||
} // namespace MobileGL::MG_Backend::DirectVulkan
|
||||
@@ -1,36 +0,0 @@
|
||||
// MobileGL - MobileGL/MG_Backend/DirectVulkan/Managers/ProgramManager.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"
|
||||
#include "MG_State/GLState/ProgramState/ProgramObject.h"
|
||||
#include "Config.h"
|
||||
#include "xxhash.h"
|
||||
|
||||
namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
class VulkanContext;
|
||||
|
||||
class ProgramManager {
|
||||
public:
|
||||
using ProgramObject = MobileGL::MG_State::GLState::ProgramObject;
|
||||
using HashType = XXH64_hash_t;
|
||||
ProgramManager(VulkanContext& ctx);
|
||||
~ProgramManager();
|
||||
|
||||
Vector<VkPipelineShaderStageCreateInfo>& CreatePipelineShaderStages(ProgramObject* programObject);
|
||||
Vector<VkPipelineShaderStageCreateInfo>* GetPipelineShaderStages(HashType hash);
|
||||
Vector<VkPipelineShaderStageCreateInfo>* GetPipelineShaderStages(ProgramObject* programObject);
|
||||
private:
|
||||
|
||||
void Cleanup();
|
||||
HashType GetHash(ProgramObject* programObject);
|
||||
VulkanContext& m_ctx;
|
||||
UnorderedMap<HashType, Vector<VkPipelineShaderStageCreateInfo>> m_shaderStageCreateInfo;
|
||||
XXH64_state_t* const m_hashState = XXH64_createState();
|
||||
};
|
||||
} // namespace MobileGL::MG_Backend::DirectVulkan
|
||||
@@ -1,269 +0,0 @@
|
||||
// MobileGL - MobileGL/MG_Backend/DirectVulkan/Managers/RenderStateManager.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 "RenderStateManager.h"
|
||||
|
||||
namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
RenderStateManager::RenderStateManager() {}
|
||||
|
||||
RenderStateManager::~RenderStateManager() {
|
||||
Cleanup();
|
||||
}
|
||||
|
||||
void RenderStateManager::Cleanup() {
|
||||
m_renderStateInfo.clear();
|
||||
XXH64_freeState(m_hashState);
|
||||
}
|
||||
|
||||
void RenderStateManager::PatchCreateInfoPointers(RenderStateInfo& stateInfo) {
|
||||
stateInfo.ColorBlendStateCreateInfo.attachmentCount =
|
||||
static_cast<Uint>(stateInfo.ColorBlendAttachmentStates.size());
|
||||
stateInfo.ColorBlendStateCreateInfo.pAttachments =
|
||||
stateInfo.ColorBlendAttachmentStates.empty() ? nullptr : stateInfo.ColorBlendAttachmentStates.data();
|
||||
|
||||
stateInfo.ViewportStateCreateInfo.viewportCount = 1;
|
||||
stateInfo.ViewportStateCreateInfo.pViewports = &stateInfo.Viewport;
|
||||
stateInfo.ViewportStateCreateInfo.scissorCount = 1;
|
||||
stateInfo.ViewportStateCreateInfo.pScissors = &stateInfo.Scissor;
|
||||
}
|
||||
|
||||
RenderStateManager::RenderStateInfo&
|
||||
RenderStateManager::CreatePipelineRenderState(const RenderStateParameters& renderState, Uint colorAttachmentCount) {
|
||||
auto hash = GetHash(renderState, colorAttachmentCount);
|
||||
MOBILEGL_ASSERT(m_renderStateInfo.find(hash) == m_renderStateInfo.end(),
|
||||
"A render state with the same hash has already been created");
|
||||
MOBILEGL_ASSERT(colorAttachmentCount > 0, "colorAttachmentCount must be greater than zero");
|
||||
MOBILEGL_ASSERT(colorAttachmentCount <= MG_State::GLState::FramebufferObject::MAX_DRAW_BUFFERS,
|
||||
"colorAttachmentCount exceeds max draw buffers");
|
||||
|
||||
RenderStateInfo stateInfo;
|
||||
|
||||
MOBILEGL_ASSERT(renderState.Viewport.z() >= 0 && renderState.Viewport.w() >= 0,
|
||||
"Viewport width/height must be non-negative");
|
||||
stateInfo.Viewport.x = static_cast<Float>(renderState.Viewport.x());
|
||||
stateInfo.Viewport.y = static_cast<Float>(renderState.Viewport.y());
|
||||
stateInfo.Viewport.width = static_cast<Float>(renderState.Viewport.z());
|
||||
stateInfo.Viewport.height = static_cast<Float>(renderState.Viewport.w());
|
||||
stateInfo.Viewport.minDepth = 0.0f;
|
||||
stateInfo.Viewport.maxDepth = 1.0f;
|
||||
|
||||
if (renderState.ScissorTestEnabled) {
|
||||
MOBILEGL_ASSERT(renderState.ScissorBox.z() >= 0 && renderState.ScissorBox.w() >= 0,
|
||||
"Scissor width/height must be non-negative");
|
||||
stateInfo.Scissor.offset.x = renderState.ScissorBox.x();
|
||||
stateInfo.Scissor.offset.y = renderState.ScissorBox.y();
|
||||
stateInfo.Scissor.extent.width = static_cast<Uint>(renderState.ScissorBox.z());
|
||||
stateInfo.Scissor.extent.height = static_cast<Uint>(renderState.ScissorBox.w());
|
||||
} else {
|
||||
stateInfo.Scissor.offset.x = renderState.Viewport.x();
|
||||
stateInfo.Scissor.offset.y = renderState.Viewport.y();
|
||||
stateInfo.Scissor.extent.width = static_cast<Uint>(renderState.Viewport.z());
|
||||
stateInfo.Scissor.extent.height = static_cast<Uint>(renderState.Viewport.w());
|
||||
}
|
||||
|
||||
stateInfo.RasterizationStateCreateInfo.depthClampEnable = VK_FALSE;
|
||||
stateInfo.RasterizationStateCreateInfo.rasterizerDiscardEnable = VK_FALSE;
|
||||
stateInfo.RasterizationStateCreateInfo.polygonMode = VK_POLYGON_MODE_FILL;
|
||||
stateInfo.RasterizationStateCreateInfo.cullMode =
|
||||
renderState.CullFaceEnabled ? ResolveCullMode(renderState.CullFaceModeSetting) : VK_CULL_MODE_NONE;
|
||||
stateInfo.RasterizationStateCreateInfo.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
|
||||
stateInfo.RasterizationStateCreateInfo.depthBiasEnable = VK_FALSE;
|
||||
stateInfo.RasterizationStateCreateInfo.lineWidth = 1.0f;
|
||||
|
||||
stateInfo.DepthStencilStateCreateInfo.depthTestEnable = renderState.DepthTestEnabled ? VK_TRUE : VK_FALSE;
|
||||
stateInfo.DepthStencilStateCreateInfo.depthWriteEnable = renderState.DepthMask ? VK_TRUE : VK_FALSE;
|
||||
stateInfo.DepthStencilStateCreateInfo.depthCompareOp = ResolveDepthCompareOp(renderState.DepthFunc);
|
||||
stateInfo.DepthStencilStateCreateInfo.depthBoundsTestEnable = VK_FALSE;
|
||||
stateInfo.DepthStencilStateCreateInfo.stencilTestEnable = VK_FALSE;
|
||||
stateInfo.DepthStencilStateCreateInfo.minDepthBounds = 0.0f;
|
||||
stateInfo.DepthStencilStateCreateInfo.maxDepthBounds = 1.0f;
|
||||
|
||||
stateInfo.ColorBlendAttachmentStates.reserve(colorAttachmentCount);
|
||||
for (Uint i = 0; i < colorAttachmentCount; ++i) {
|
||||
const auto& blendState = renderState.BlendStates[i];
|
||||
VkPipelineColorBlendAttachmentState attachment{};
|
||||
attachment.blendEnable = blendState.Enabled ? VK_TRUE : VK_FALSE;
|
||||
attachment.srcColorBlendFactor = ResolveBlendFactor(blendState.SrcFactorRGB);
|
||||
attachment.dstColorBlendFactor = ResolveBlendFactor(blendState.DstFactorRGB);
|
||||
attachment.colorBlendOp = VK_BLEND_OP_ADD;
|
||||
attachment.srcAlphaBlendFactor = ResolveBlendFactor(blendState.SrcFactorAlpha);
|
||||
attachment.dstAlphaBlendFactor = ResolveBlendFactor(blendState.DstFactorAlpha);
|
||||
attachment.alphaBlendOp = VK_BLEND_OP_ADD;
|
||||
attachment.colorWriteMask = ResolveColorWriteMask(renderState.ColorMask);
|
||||
stateInfo.ColorBlendAttachmentStates.emplace_back(attachment);
|
||||
}
|
||||
|
||||
stateInfo.ColorBlendStateCreateInfo.logicOpEnable = VK_FALSE;
|
||||
stateInfo.ColorBlendStateCreateInfo.logicOp = VK_LOGIC_OP_COPY;
|
||||
stateInfo.ColorBlendStateCreateInfo.blendConstants[0] = 0.0f;
|
||||
stateInfo.ColorBlendStateCreateInfo.blendConstants[1] = 0.0f;
|
||||
stateInfo.ColorBlendStateCreateInfo.blendConstants[2] = 0.0f;
|
||||
stateInfo.ColorBlendStateCreateInfo.blendConstants[3] = 0.0f;
|
||||
|
||||
PatchCreateInfoPointers(stateInfo);
|
||||
|
||||
auto [it, inserted] = m_renderStateInfo.emplace(hash, Move(stateInfo));
|
||||
MOBILEGL_ASSERT(inserted, "Failed to cache pipeline render state create info");
|
||||
PatchCreateInfoPointers(it->second);
|
||||
return it->second;
|
||||
}
|
||||
|
||||
RenderStateManager::RenderStateInfo* RenderStateManager::GetPipelineRenderState(HashType hash) {
|
||||
auto it = m_renderStateInfo.find(hash);
|
||||
if (it == m_renderStateInfo.end()) return nullptr;
|
||||
return &it->second;
|
||||
}
|
||||
|
||||
RenderStateManager::RenderStateInfo*
|
||||
RenderStateManager::GetPipelineRenderState(const RenderStateParameters& renderState, Uint colorAttachmentCount) {
|
||||
return GetPipelineRenderState(GetHash(renderState, colorAttachmentCount));
|
||||
}
|
||||
|
||||
RenderStateManager::HashType RenderStateManager::GetHash(const RenderStateParameters& renderState,
|
||||
Uint colorAttachmentCount) {
|
||||
MOBILEGL_ASSERT(m_hashState != nullptr, "Hash state should already be initialized");
|
||||
MOBILEGL_ASSERT(colorAttachmentCount > 0, "colorAttachmentCount must be greater than zero");
|
||||
MOBILEGL_ASSERT(colorAttachmentCount <= MG_State::GLState::FramebufferObject::MAX_DRAW_BUFFERS,
|
||||
"colorAttachmentCount exceeds max draw buffers");
|
||||
|
||||
XXH64_hash_t const seed = MG_Config::CacheVersion;
|
||||
auto errc = XXH64_reset(m_hashState, seed);
|
||||
MOBILEGL_ASSERT(errc == XXH_OK, "Hash state reset failed");
|
||||
|
||||
const Int viewport[4] = {renderState.Viewport.x(), renderState.Viewport.y(), renderState.Viewport.z(),
|
||||
renderState.Viewport.w()};
|
||||
errc = XXH64_update(m_hashState, viewport, sizeof(viewport));
|
||||
MOBILEGL_ASSERT(errc == XXH_OK, "Hash state update failed");
|
||||
|
||||
for (Uint i = 0; i < colorAttachmentCount; ++i) {
|
||||
const auto& blendState = renderState.BlendStates[i];
|
||||
errc = XXH64_update(m_hashState, &blendState.Enabled, sizeof(blendState.Enabled));
|
||||
MOBILEGL_ASSERT(errc == XXH_OK, "Hash state update failed");
|
||||
errc = XXH64_update(m_hashState, &blendState.SrcFactorRGB, sizeof(blendState.SrcFactorRGB));
|
||||
MOBILEGL_ASSERT(errc == XXH_OK, "Hash state update failed");
|
||||
errc = XXH64_update(m_hashState, &blendState.DstFactorRGB, sizeof(blendState.DstFactorRGB));
|
||||
MOBILEGL_ASSERT(errc == XXH_OK, "Hash state update failed");
|
||||
errc = XXH64_update(m_hashState, &blendState.SrcFactorAlpha, sizeof(blendState.SrcFactorAlpha));
|
||||
MOBILEGL_ASSERT(errc == XXH_OK, "Hash state update failed");
|
||||
errc = XXH64_update(m_hashState, &blendState.DstFactorAlpha, sizeof(blendState.DstFactorAlpha));
|
||||
MOBILEGL_ASSERT(errc == XXH_OK, "Hash state update failed");
|
||||
}
|
||||
|
||||
errc = XXH64_update(m_hashState, &renderState.DepthTestEnabled, sizeof(renderState.DepthTestEnabled));
|
||||
MOBILEGL_ASSERT(errc == XXH_OK, "Hash state update failed");
|
||||
errc = XXH64_update(m_hashState, &renderState.DepthFunc, sizeof(renderState.DepthFunc));
|
||||
MOBILEGL_ASSERT(errc == XXH_OK, "Hash state update failed");
|
||||
errc = XXH64_update(m_hashState, &renderState.DepthMask, sizeof(renderState.DepthMask));
|
||||
MOBILEGL_ASSERT(errc == XXH_OK, "Hash state update failed");
|
||||
|
||||
const Bool colorMask[4] = {renderState.ColorMask.x(), renderState.ColorMask.y(), renderState.ColorMask.z(),
|
||||
renderState.ColorMask.w()};
|
||||
errc = XXH64_update(m_hashState, colorMask, sizeof(colorMask));
|
||||
MOBILEGL_ASSERT(errc == XXH_OK, "Hash state update failed");
|
||||
|
||||
errc = XXH64_update(m_hashState, &renderState.CullFaceEnabled, sizeof(renderState.CullFaceEnabled));
|
||||
MOBILEGL_ASSERT(errc == XXH_OK, "Hash state update failed");
|
||||
errc = XXH64_update(m_hashState, &renderState.CullFaceModeSetting, sizeof(renderState.CullFaceModeSetting));
|
||||
MOBILEGL_ASSERT(errc == XXH_OK, "Hash state update failed");
|
||||
|
||||
errc = XXH64_update(m_hashState, &renderState.ScissorTestEnabled, sizeof(renderState.ScissorTestEnabled));
|
||||
MOBILEGL_ASSERT(errc == XXH_OK, "Hash state update failed");
|
||||
const Int scissor[4] = {renderState.ScissorBox.x(), renderState.ScissorBox.y(), renderState.ScissorBox.z(),
|
||||
renderState.ScissorBox.w()};
|
||||
errc = XXH64_update(m_hashState, scissor, sizeof(scissor));
|
||||
MOBILEGL_ASSERT(errc == XXH_OK, "Hash state update failed");
|
||||
|
||||
errc = XXH64_update(m_hashState, &colorAttachmentCount, sizeof(colorAttachmentCount));
|
||||
MOBILEGL_ASSERT(errc == XXH_OK, "Hash state update failed");
|
||||
|
||||
return XXH64_digest(m_hashState);
|
||||
}
|
||||
|
||||
VkBlendFactor RenderStateManager::ResolveBlendFactor(BlendFactor factor) {
|
||||
switch (factor) {
|
||||
case BlendFactor::Zero:
|
||||
return VK_BLEND_FACTOR_ZERO;
|
||||
case BlendFactor::One:
|
||||
return VK_BLEND_FACTOR_ONE;
|
||||
case BlendFactor::SrcColor:
|
||||
return VK_BLEND_FACTOR_SRC_COLOR;
|
||||
case BlendFactor::OneMinusSrcColor:
|
||||
return VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR;
|
||||
case BlendFactor::DstColor:
|
||||
return VK_BLEND_FACTOR_DST_COLOR;
|
||||
case BlendFactor::OneMinusDstColor:
|
||||
return VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR;
|
||||
case BlendFactor::SrcAlpha:
|
||||
return VK_BLEND_FACTOR_SRC_ALPHA;
|
||||
case BlendFactor::OneMinusSrcAlpha:
|
||||
return VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
|
||||
case BlendFactor::DstAlpha:
|
||||
return VK_BLEND_FACTOR_DST_ALPHA;
|
||||
case BlendFactor::OneMinusDstAlpha:
|
||||
return VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA;
|
||||
case BlendFactor::ConstantColor:
|
||||
return VK_BLEND_FACTOR_CONSTANT_COLOR;
|
||||
case BlendFactor::OneMinusConstantColor:
|
||||
return VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR;
|
||||
case BlendFactor::ConstantAlpha:
|
||||
return VK_BLEND_FACTOR_CONSTANT_ALPHA;
|
||||
case BlendFactor::OneMinusConstantAlpha:
|
||||
return VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA;
|
||||
default:
|
||||
MOBILEGL_ASSERT(false, "Unsupported blend factor");
|
||||
return VK_BLEND_FACTOR_ONE;
|
||||
}
|
||||
}
|
||||
|
||||
VkCompareOp RenderStateManager::ResolveDepthCompareOp(DepthTestFunc func) {
|
||||
switch (func) {
|
||||
case DepthTestFunc::Never:
|
||||
return VK_COMPARE_OP_NEVER;
|
||||
case DepthTestFunc::Less:
|
||||
return VK_COMPARE_OP_LESS;
|
||||
case DepthTestFunc::Equal:
|
||||
return VK_COMPARE_OP_EQUAL;
|
||||
case DepthTestFunc::LessEqual:
|
||||
return VK_COMPARE_OP_LESS_OR_EQUAL;
|
||||
case DepthTestFunc::Greater:
|
||||
return VK_COMPARE_OP_GREATER;
|
||||
case DepthTestFunc::NotEqual:
|
||||
return VK_COMPARE_OP_NOT_EQUAL;
|
||||
case DepthTestFunc::GreaterEqual:
|
||||
return VK_COMPARE_OP_GREATER_OR_EQUAL;
|
||||
case DepthTestFunc::Always:
|
||||
return VK_COMPARE_OP_ALWAYS;
|
||||
default:
|
||||
MOBILEGL_ASSERT(false, "Unsupported depth compare function");
|
||||
return VK_COMPARE_OP_LESS;
|
||||
}
|
||||
}
|
||||
|
||||
VkCullModeFlags RenderStateManager::ResolveCullMode(CullFaceMode mode) {
|
||||
switch (mode) {
|
||||
case CullFaceMode::Front:
|
||||
return VK_CULL_MODE_FRONT_BIT;
|
||||
case CullFaceMode::Back:
|
||||
return VK_CULL_MODE_BACK_BIT;
|
||||
case CullFaceMode::FrontAndBack:
|
||||
return VK_CULL_MODE_FRONT_AND_BACK;
|
||||
default:
|
||||
MOBILEGL_ASSERT(false, "Unsupported cull face mode");
|
||||
return VK_CULL_MODE_BACK_BIT;
|
||||
}
|
||||
}
|
||||
|
||||
VkColorComponentFlags RenderStateManager::ResolveColorWriteMask(const BoolVec4& mask) {
|
||||
VkColorComponentFlags vkMask = 0;
|
||||
if (mask.r()) vkMask |= VK_COLOR_COMPONENT_R_BIT;
|
||||
if (mask.g()) vkMask |= VK_COLOR_COMPONENT_G_BIT;
|
||||
if (mask.b()) vkMask |= VK_COLOR_COMPONENT_B_BIT;
|
||||
if (mask.a()) vkMask |= VK_COLOR_COMPONENT_A_BIT;
|
||||
return vkMask;
|
||||
}
|
||||
} // namespace MobileGL::MG_Backend::DirectVulkan
|
||||
@@ -1,54 +0,0 @@
|
||||
// MobileGL - MobileGL/MG_Backend/DirectVulkan/Managers/RenderStateManager.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"
|
||||
#include "MG_State/GLState/RenderState/RenderState.h"
|
||||
#include "Config.h"
|
||||
#include "xxhash.h"
|
||||
|
||||
namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
class RenderStateManager {
|
||||
public:
|
||||
using RenderStateParameters = MobileGL::RenderStateParameters;
|
||||
using HashType = XXH64_hash_t;
|
||||
|
||||
struct RenderStateInfo {
|
||||
VkPipelineColorBlendStateCreateInfo ColorBlendStateCreateInfo{
|
||||
VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO};
|
||||
Vector<VkPipelineColorBlendAttachmentState> ColorBlendAttachmentStates;
|
||||
VkPipelineRasterizationStateCreateInfo RasterizationStateCreateInfo{
|
||||
VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO};
|
||||
VkPipelineViewportStateCreateInfo ViewportStateCreateInfo{
|
||||
VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO};
|
||||
VkPipelineDepthStencilStateCreateInfo DepthStencilStateCreateInfo{
|
||||
VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO};
|
||||
VkViewport Viewport{};
|
||||
VkRect2D Scissor{};
|
||||
};
|
||||
|
||||
RenderStateManager();
|
||||
~RenderStateManager();
|
||||
|
||||
RenderStateInfo& CreatePipelineRenderState(const RenderStateParameters& renderState, Uint colorAttachmentCount);
|
||||
RenderStateInfo* GetPipelineRenderState(HashType hash);
|
||||
RenderStateInfo* GetPipelineRenderState(const RenderStateParameters& renderState, Uint colorAttachmentCount);
|
||||
|
||||
private:
|
||||
void Cleanup();
|
||||
static void PatchCreateInfoPointers(RenderStateInfo& stateInfo);
|
||||
HashType GetHash(const RenderStateParameters& renderState, Uint colorAttachmentCount);
|
||||
static VkBlendFactor ResolveBlendFactor(BlendFactor factor);
|
||||
static VkCompareOp ResolveDepthCompareOp(DepthTestFunc func);
|
||||
static VkCullModeFlags ResolveCullMode(CullFaceMode mode);
|
||||
static VkColorComponentFlags ResolveColorWriteMask(const BoolVec4& mask);
|
||||
|
||||
UnorderedMap<HashType, RenderStateInfo> m_renderStateInfo;
|
||||
XXH64_state_t* const m_hashState = XXH64_createState();
|
||||
};
|
||||
} // namespace MobileGL::MG_Backend::DirectVulkan
|
||||
@@ -1,227 +0,0 @@
|
||||
// MobileGL - MobileGL/MG_Backend/DirectVulkan/Managers/VertexInputStateManager.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 "VertexInputStateManager.h"
|
||||
|
||||
namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
VertexInputStateManager::VertexInputStateManager() {}
|
||||
|
||||
VertexInputStateManager::~VertexInputStateManager() {
|
||||
Cleanup();
|
||||
}
|
||||
|
||||
void VertexInputStateManager::Cleanup() {
|
||||
m_vertexInputStateInfo.clear();
|
||||
XXH64_freeState(m_hashState);
|
||||
}
|
||||
|
||||
void VertexInputStateManager::PatchCreateInfoPointers(VertexInputStateInfo& stateInfo) {
|
||||
stateInfo.CreateInfo.vertexBindingDescriptionCount = static_cast<Uint>(stateInfo.BindingDescriptions.size());
|
||||
stateInfo.CreateInfo.pVertexBindingDescriptions =
|
||||
stateInfo.BindingDescriptions.empty() ? nullptr : stateInfo.BindingDescriptions.data();
|
||||
stateInfo.CreateInfo.vertexAttributeDescriptionCount = static_cast<Uint>(stateInfo.AttributeDescriptions.size());
|
||||
stateInfo.CreateInfo.pVertexAttributeDescriptions =
|
||||
stateInfo.AttributeDescriptions.empty() ? nullptr : stateInfo.AttributeDescriptions.data();
|
||||
}
|
||||
|
||||
VertexInputStateManager::VertexInputStateInfo&
|
||||
VertexInputStateManager::CreatePipelineVertexInputState(VertexArrayObject* vaoObject) {
|
||||
auto hash = GetHash(vaoObject);
|
||||
MOBILEGL_ASSERT(m_vertexInputStateInfo.find(hash) == m_vertexInputStateInfo.end(),
|
||||
"A VAO vertex input state with the same hash has already been created");
|
||||
|
||||
VertexInputStateInfo stateInfo;
|
||||
const auto& allAttributes = vaoObject->GetAllAttributes();
|
||||
|
||||
for (Uint attribIndex = 0; attribIndex < allAttributes.size(); ++attribIndex) {
|
||||
const auto& attrib = allAttributes[attribIndex];
|
||||
if (!attrib.Enabled) continue;
|
||||
|
||||
MOBILEGL_ASSERT(attrib.Size >= 1 && attrib.Size <= 4, "Vertex attribute size out of range");
|
||||
MOBILEGL_ASSERT(attrib.Divisor <= 1,
|
||||
"Vulkan core pipeline vertex input only supports divisor 0/1 without extra extensions");
|
||||
|
||||
VkVertexInputBindingDescription bindingDesc{};
|
||||
bindingDesc.binding = attribIndex;
|
||||
bindingDesc.inputRate = (attrib.Divisor == 0) ? VK_VERTEX_INPUT_RATE_VERTEX : VK_VERTEX_INPUT_RATE_INSTANCE;
|
||||
|
||||
auto componentByteSize = GetDataTypeByteSize(attrib.Type);
|
||||
auto computedStride = static_cast<Uint>(componentByteSize * static_cast<Uint>(attrib.Size));
|
||||
bindingDesc.stride = (attrib.Stride > 0) ? static_cast<Uint>(attrib.Stride) : computedStride;
|
||||
stateInfo.BindingDescriptions.emplace_back(bindingDesc);
|
||||
|
||||
VkVertexInputAttributeDescription attrDesc{};
|
||||
attrDesc.location = attribIndex;
|
||||
attrDesc.binding = attribIndex;
|
||||
attrDesc.format = ResolveVertexFormat(attrib);
|
||||
attrDesc.offset = static_cast<Uint>(attrib.Offset);
|
||||
stateInfo.AttributeDescriptions.emplace_back(attrDesc);
|
||||
}
|
||||
|
||||
PatchCreateInfoPointers(stateInfo);
|
||||
|
||||
auto [it, inserted] = m_vertexInputStateInfo.emplace(hash, Move(stateInfo));
|
||||
MOBILEGL_ASSERT(inserted, "Failed to cache pipeline vertex input state create info");
|
||||
PatchCreateInfoPointers(it->second);
|
||||
return it->second;
|
||||
}
|
||||
|
||||
VertexInputStateManager::VertexInputStateInfo* VertexInputStateManager::GetPipelineVertexInputState(HashType hash) {
|
||||
auto it = m_vertexInputStateInfo.find(hash);
|
||||
if (it == m_vertexInputStateInfo.end()) return nullptr;
|
||||
return &it->second;
|
||||
}
|
||||
|
||||
VertexInputStateManager::VertexInputStateInfo*
|
||||
VertexInputStateManager::GetPipelineVertexInputState(VertexArrayObject* vaoObject) {
|
||||
return GetPipelineVertexInputState(GetHash(vaoObject));
|
||||
}
|
||||
|
||||
VertexInputStateManager::HashType VertexInputStateManager::GetHash(VertexArrayObject* vaoObject) {
|
||||
MOBILEGL_ASSERT(vaoObject != nullptr, "vao object is null");
|
||||
MOBILEGL_ASSERT(m_hashState != nullptr, "Hash state should already be initialized");
|
||||
|
||||
XXH64_hash_t const seed = MG_Config::CacheVersion;
|
||||
auto errc = XXH64_reset(m_hashState, seed);
|
||||
MOBILEGL_ASSERT(errc == XXH_OK, "Hash state reset failed");
|
||||
|
||||
const auto& allAttributes = vaoObject->GetAllAttributes();
|
||||
for (const auto& attrib : allAttributes) {
|
||||
errc = XXH64_update(m_hashState, &attrib.Enabled, sizeof(attrib.Enabled));
|
||||
MOBILEGL_ASSERT(errc == XXH_OK, "Hash state update failed");
|
||||
errc = XXH64_update(m_hashState, &attrib.Size, sizeof(attrib.Size));
|
||||
MOBILEGL_ASSERT(errc == XXH_OK, "Hash state update failed");
|
||||
errc = XXH64_update(m_hashState, &attrib.Type, sizeof(attrib.Type));
|
||||
MOBILEGL_ASSERT(errc == XXH_OK, "Hash state update failed");
|
||||
errc = XXH64_update(m_hashState, &attrib.Normalized, sizeof(attrib.Normalized));
|
||||
MOBILEGL_ASSERT(errc == XXH_OK, "Hash state update failed");
|
||||
errc = XXH64_update(m_hashState, &attrib.Stride, sizeof(attrib.Stride));
|
||||
MOBILEGL_ASSERT(errc == XXH_OK, "Hash state update failed");
|
||||
errc = XXH64_update(m_hashState, &attrib.Offset, sizeof(attrib.Offset));
|
||||
MOBILEGL_ASSERT(errc == XXH_OK, "Hash state update failed");
|
||||
errc = XXH64_update(m_hashState, &attrib.IsInteger, sizeof(attrib.IsInteger));
|
||||
MOBILEGL_ASSERT(errc == XXH_OK, "Hash state update failed");
|
||||
errc = XXH64_update(m_hashState, &attrib.Divisor, sizeof(attrib.Divisor));
|
||||
MOBILEGL_ASSERT(errc == XXH_OK, "Hash state update failed");
|
||||
}
|
||||
|
||||
return XXH64_digest(m_hashState);
|
||||
}
|
||||
|
||||
Uint VertexInputStateManager::GetDataTypeByteSize(DataType type) {
|
||||
switch (type) {
|
||||
case DataType::Int8:
|
||||
case DataType::Uint8:
|
||||
return 1;
|
||||
case DataType::Int16:
|
||||
case DataType::Uint16:
|
||||
case DataType::Float16:
|
||||
return 2;
|
||||
case DataType::Int32:
|
||||
case DataType::Uint32:
|
||||
case DataType::Float32:
|
||||
case DataType::Fixed32:
|
||||
return 4;
|
||||
case DataType::Float64:
|
||||
return 8;
|
||||
default:
|
||||
MOBILEGL_ASSERT(false, "Unsupported vertex data type");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
VkFormat VertexInputStateManager::ResolveVertexFormat(const MG_State::GLState::VertexAttribute& attrib) {
|
||||
auto size = attrib.Size;
|
||||
|
||||
auto selectFormat = [size](VkFormat c1, VkFormat c2, VkFormat c3, VkFormat c4) {
|
||||
switch (size) {
|
||||
case 1:
|
||||
return c1;
|
||||
case 2:
|
||||
return c2;
|
||||
case 3:
|
||||
return c3;
|
||||
case 4:
|
||||
return c4;
|
||||
default:
|
||||
return VK_FORMAT_UNDEFINED;
|
||||
}
|
||||
};
|
||||
|
||||
if (attrib.IsInteger) {
|
||||
MOBILEGL_ASSERT(!attrib.Normalized, "Integer attributes cannot be normalized in Vulkan integer pipeline IO");
|
||||
switch (attrib.Type) {
|
||||
case DataType::Int8:
|
||||
return selectFormat(VK_FORMAT_R8_SINT, VK_FORMAT_R8G8_SINT, VK_FORMAT_R8G8B8_SINT,
|
||||
VK_FORMAT_R8G8B8A8_SINT);
|
||||
case DataType::Uint8:
|
||||
return selectFormat(VK_FORMAT_R8_UINT, VK_FORMAT_R8G8_UINT, VK_FORMAT_R8G8B8_UINT,
|
||||
VK_FORMAT_R8G8B8A8_UINT);
|
||||
case DataType::Int16:
|
||||
return selectFormat(VK_FORMAT_R16_SINT, VK_FORMAT_R16G16_SINT, VK_FORMAT_R16G16B16_SINT,
|
||||
VK_FORMAT_R16G16B16A16_SINT);
|
||||
case DataType::Uint16:
|
||||
return selectFormat(VK_FORMAT_R16_UINT, VK_FORMAT_R16G16_UINT, VK_FORMAT_R16G16B16_UINT,
|
||||
VK_FORMAT_R16G16B16A16_UINT);
|
||||
case DataType::Int32:
|
||||
return selectFormat(VK_FORMAT_R32_SINT, VK_FORMAT_R32G32_SINT, VK_FORMAT_R32G32B32_SINT,
|
||||
VK_FORMAT_R32G32B32A32_SINT);
|
||||
case DataType::Uint32:
|
||||
return selectFormat(VK_FORMAT_R32_UINT, VK_FORMAT_R32G32_UINT, VK_FORMAT_R32G32B32_UINT,
|
||||
VK_FORMAT_R32G32B32A32_UINT);
|
||||
default:
|
||||
MOBILEGL_ASSERT(false, "Unsupported integer vertex attribute data type");
|
||||
return VK_FORMAT_UNDEFINED;
|
||||
}
|
||||
}
|
||||
|
||||
if (attrib.Normalized) {
|
||||
switch (attrib.Type) {
|
||||
case DataType::Int8:
|
||||
return selectFormat(VK_FORMAT_R8_SNORM, VK_FORMAT_R8G8_SNORM, VK_FORMAT_R8G8B8_SNORM,
|
||||
VK_FORMAT_R8G8B8A8_SNORM);
|
||||
case DataType::Uint8:
|
||||
return selectFormat(VK_FORMAT_R8_UNORM, VK_FORMAT_R8G8_UNORM, VK_FORMAT_R8G8B8_UNORM,
|
||||
VK_FORMAT_R8G8B8A8_UNORM);
|
||||
case DataType::Int16:
|
||||
return selectFormat(VK_FORMAT_R16_SNORM, VK_FORMAT_R16G16_SNORM, VK_FORMAT_R16G16B16_SNORM,
|
||||
VK_FORMAT_R16G16B16A16_SNORM);
|
||||
case DataType::Uint16:
|
||||
return selectFormat(VK_FORMAT_R16_UNORM, VK_FORMAT_R16G16_UNORM, VK_FORMAT_R16G16B16_UNORM,
|
||||
VK_FORMAT_R16G16B16A16_UNORM);
|
||||
default:
|
||||
MOBILEGL_ASSERT(false, "Unsupported normalized vertex attribute data type");
|
||||
return VK_FORMAT_UNDEFINED;
|
||||
}
|
||||
}
|
||||
|
||||
switch (attrib.Type) {
|
||||
case DataType::Float16:
|
||||
return selectFormat(VK_FORMAT_R16_SFLOAT, VK_FORMAT_R16G16_SFLOAT, VK_FORMAT_R16G16B16_SFLOAT,
|
||||
VK_FORMAT_R16G16B16A16_SFLOAT);
|
||||
case DataType::Float32:
|
||||
return selectFormat(VK_FORMAT_R32_SFLOAT, VK_FORMAT_R32G32_SFLOAT, VK_FORMAT_R32G32B32_SFLOAT,
|
||||
VK_FORMAT_R32G32B32A32_SFLOAT);
|
||||
case DataType::Int8:
|
||||
return selectFormat(VK_FORMAT_R8_SSCALED, VK_FORMAT_R8G8_SSCALED, VK_FORMAT_R8G8B8_SSCALED,
|
||||
VK_FORMAT_R8G8B8A8_SSCALED);
|
||||
case DataType::Uint8:
|
||||
return selectFormat(VK_FORMAT_R8_USCALED, VK_FORMAT_R8G8_USCALED, VK_FORMAT_R8G8B8_USCALED,
|
||||
VK_FORMAT_R8G8B8A8_USCALED);
|
||||
case DataType::Int16:
|
||||
return selectFormat(VK_FORMAT_R16_SSCALED, VK_FORMAT_R16G16_SSCALED, VK_FORMAT_R16G16B16_SSCALED,
|
||||
VK_FORMAT_R16G16B16A16_SSCALED);
|
||||
case DataType::Uint16:
|
||||
return selectFormat(VK_FORMAT_R16_USCALED, VK_FORMAT_R16G16_USCALED, VK_FORMAT_R16G16B16_USCALED,
|
||||
VK_FORMAT_R16G16B16A16_USCALED);
|
||||
default:
|
||||
MOBILEGL_ASSERT(false, "Unsupported floating-point vertex attribute data type");
|
||||
return VK_FORMAT_UNDEFINED;
|
||||
}
|
||||
}
|
||||
} // namespace MobileGL::MG_Backend::DirectVulkan
|
||||
@@ -1,44 +0,0 @@
|
||||
// MobileGL - MobileGL/MG_Backend/DirectVulkan/Managers/VertexInputStateManager.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"
|
||||
#include "MG_State/GLState/VertexArrayState/VertexArrayObject.h"
|
||||
#include "Config.h"
|
||||
#include "xxhash.h"
|
||||
|
||||
namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
class VertexInputStateManager {
|
||||
public:
|
||||
using VertexArrayObject = MobileGL::MG_State::GLState::VertexArrayObject;
|
||||
using HashType = XXH64_hash_t;
|
||||
|
||||
struct VertexInputStateInfo {
|
||||
VkPipelineVertexInputStateCreateInfo CreateInfo{VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO};
|
||||
Vector<VkVertexInputBindingDescription> BindingDescriptions;
|
||||
Vector<VkVertexInputAttributeDescription> AttributeDescriptions;
|
||||
};
|
||||
|
||||
VertexInputStateManager();
|
||||
~VertexInputStateManager();
|
||||
|
||||
VertexInputStateInfo& CreatePipelineVertexInputState(VertexArrayObject* vaoObject);
|
||||
VertexInputStateInfo* GetPipelineVertexInputState(HashType hash);
|
||||
VertexInputStateInfo* GetPipelineVertexInputState(VertexArrayObject* vaoObject);
|
||||
|
||||
private:
|
||||
void Cleanup();
|
||||
static void PatchCreateInfoPointers(VertexInputStateInfo& stateInfo);
|
||||
HashType GetHash(VertexArrayObject* vaoObject);
|
||||
static VkFormat ResolveVertexFormat(const MG_State::GLState::VertexAttribute& attrib);
|
||||
static Uint GetDataTypeByteSize(DataType type);
|
||||
|
||||
UnorderedMap<HashType, VertexInputStateInfo> m_vertexInputStateInfo;
|
||||
XXH64_state_t* const m_hashState = XXH64_createState();
|
||||
};
|
||||
} // namespace MobileGL::MG_Backend::DirectVulkan
|
||||
@@ -10,18 +10,6 @@
|
||||
|
||||
#include "MG_State/GLState/ProgramState/ProgramObject.h"
|
||||
|
||||
// #ifndef VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR
|
||||
// #define VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR 0x00000001
|
||||
// #endif
|
||||
//
|
||||
// #ifndef VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME
|
||||
// #define VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME "VK_KHR_portability_enumeration"
|
||||
// #endif
|
||||
//
|
||||
// #ifndef VK_EXT_METAL_SURFACE_EXTENSION_NAME
|
||||
// #define VK_EXT_METAL_SURFACE_EXTENSION_NAME "VK_EXT_metal_surface"
|
||||
// #endif
|
||||
|
||||
namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
VkBool32 VulkanRenderer::DebugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
|
||||
VkDebugUtilsMessageTypeFlagsEXT messageType,
|
||||
|
||||
Reference in New Issue
Block a user