mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-07 19:58:32 +09:00
[Feat] (MG_Backend/DirectVulkan): vertex input state builder
This commit is contained in:
@@ -214,6 +214,7 @@ set(SOURCE_FILES
|
||||
MobileGL/MG_Backend/DirectVulkan/Renderer/SwapchainObject.cpp
|
||||
MobileGL/MG_Backend/DirectVulkan/Renderer/FrameContext.cpp
|
||||
MobileGL/MG_Backend/DirectVulkan/Renderer/ProgramFactory.cpp
|
||||
MobileGL/MG_Backend/DirectVulkan/Renderer/VertexInputStateBuilder.cpp
|
||||
MobileGL/MG_Backend/DirectVulkan/Renderer/VkBufferObject.cpp
|
||||
|
||||
MobileGL/MG_State/GLState/Core.cpp
|
||||
|
||||
@@ -85,6 +85,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
|
||||
void DrawArrays(GLenum mode, GLint first, GLsizei count) {
|
||||
MOBILEGL_ASSERT(pVulkanRenderer, "DirectVulkan::DrawArrays called with null VulkanRenderer");
|
||||
MOBILEGL_ASSERT(MG_State::pGLContext, "DirectVulkan::DrawArrays called with null GL context");
|
||||
|
||||
if (first < 0) {
|
||||
MGLOG_W("DrawArrays skipped: first (%d) must be non-negative", first);
|
||||
@@ -105,7 +106,39 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
return;
|
||||
}
|
||||
|
||||
pVulkanRenderer->DrawArrays(mode, first, count);
|
||||
DrawArrayPayload payload{};
|
||||
payload.mode = mode;
|
||||
payload.first = first;
|
||||
payload.count = count;
|
||||
|
||||
const auto vao = MG_State::pGLContext->GetBoundVertexArray();
|
||||
if (vao) {
|
||||
const auto& attr0 = vao->GetAttribute(0);
|
||||
if (attr0.Enabled && attr0.Buffer) {
|
||||
const auto positionData = attr0.Buffer->GetDataReadOnly();
|
||||
if (positionData && !positionData->empty()) {
|
||||
payload.hasPositionStream = true;
|
||||
payload.positionData = positionData->data();
|
||||
payload.positionDataSizeBytes = attr0.Buffer->GetSize();
|
||||
payload.positionOffsetBytes = attr0.Offset;
|
||||
payload.positionStrideBytes = attr0.Stride > 0 ? static_cast<SizeT>(attr0.Stride) : 0;
|
||||
payload.positionSize = attr0.Size;
|
||||
payload.positionNormalized = attr0.Normalized;
|
||||
|
||||
switch (attr0.Type) {
|
||||
case DataType::Float32:
|
||||
payload.positionType = GL_FLOAT;
|
||||
break;
|
||||
default:
|
||||
payload.positionType = GL_FLOAT;
|
||||
payload.hasPositionStream = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pVulkanRenderer->DrawArrays(payload);
|
||||
}
|
||||
} // namespace MobileGL::MG_Backend::DirectVulkan
|
||||
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
// MobileGL - MobileGL/MG_Backend/DirectVulkan/Renderer/VertexInputStateBuilder.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 "VertexInputStateBuilder.h"
|
||||
|
||||
namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
VertexInputStateBuilder::VertexInputStateBuilder() {
|
||||
Reset();
|
||||
}
|
||||
|
||||
void VertexInputStateBuilder::Reset() {
|
||||
m_bindings.clear();
|
||||
m_attributes.clear();
|
||||
|
||||
m_state = {};
|
||||
m_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
|
||||
m_state.vertexBindingDescriptionCount = 0;
|
||||
m_state.pVertexBindingDescriptions = nullptr;
|
||||
m_state.vertexAttributeDescriptionCount = 0;
|
||||
m_state.pVertexAttributeDescriptions = nullptr;
|
||||
}
|
||||
|
||||
VertexInputStateBuilder& VertexInputStateBuilder::AddBinding(
|
||||
Uint32 binding, Uint32 stride, VkVertexInputRate inputRate) {
|
||||
VkVertexInputBindingDescription desc{};
|
||||
desc.binding = binding;
|
||||
desc.stride = stride;
|
||||
desc.inputRate = inputRate;
|
||||
m_bindings.push_back(desc);
|
||||
return *this;
|
||||
}
|
||||
|
||||
VertexInputStateBuilder& VertexInputStateBuilder::AddAttribute(
|
||||
Uint32 location, Uint32 binding, VkFormat format, Uint32 offset) {
|
||||
VkVertexInputAttributeDescription desc{};
|
||||
desc.location = location;
|
||||
desc.binding = binding;
|
||||
desc.format = format;
|
||||
desc.offset = offset;
|
||||
m_attributes.push_back(desc);
|
||||
return *this;
|
||||
}
|
||||
|
||||
const VkPipelineVertexInputStateCreateInfo& VertexInputStateBuilder::Build() {
|
||||
m_state.vertexBindingDescriptionCount = static_cast<Uint32>(m_bindings.size());
|
||||
m_state.pVertexBindingDescriptions = m_bindings.empty() ? nullptr : m_bindings.data();
|
||||
m_state.vertexAttributeDescriptionCount = static_cast<Uint32>(m_attributes.size());
|
||||
m_state.pVertexAttributeDescriptions = m_attributes.empty() ? nullptr : m_attributes.data();
|
||||
return m_state;
|
||||
}
|
||||
} // namespace MobileGL::MG_Backend::DirectVulkan
|
||||
@@ -0,0 +1,29 @@
|
||||
// MobileGL - MobileGL/MG_Backend/DirectVulkan/Renderer/VertexInputStateBuilder.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::MG_Backend::DirectVulkan {
|
||||
class VertexInputStateBuilder {
|
||||
public:
|
||||
VertexInputStateBuilder();
|
||||
|
||||
void Reset();
|
||||
VertexInputStateBuilder& AddBinding(
|
||||
Uint32 binding, Uint32 stride, VkVertexInputRate inputRate = VK_VERTEX_INPUT_RATE_VERTEX);
|
||||
VertexInputStateBuilder& AddAttribute(Uint32 location, Uint32 binding, VkFormat format, Uint32 offset);
|
||||
|
||||
const VkPipelineVertexInputStateCreateInfo& Build();
|
||||
|
||||
private:
|
||||
VkPipelineVertexInputStateCreateInfo m_state{};
|
||||
Vector<VkVertexInputBindingDescription> m_bindings;
|
||||
Vector<VkVertexInputAttributeDescription> m_attributes;
|
||||
};
|
||||
} // namespace MobileGL::MG_Backend::DirectVulkan
|
||||
@@ -7,6 +7,7 @@
|
||||
// End of Source File Header
|
||||
|
||||
#include "VulkanRenderer.h"
|
||||
#include "VertexInputStateBuilder.h"
|
||||
|
||||
#include "MG_State/GLState/ProgramState/ProgramObject.h"
|
||||
|
||||
@@ -112,9 +113,8 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
dynamicState.dynamicStateCount = static_cast<uint32_t>(std::size(s_dynamicStates));
|
||||
dynamicState.pDynamicStates = s_dynamicStates;
|
||||
|
||||
VkPipelineVertexInputStateCreateInfo vertexInput{VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO};
|
||||
vertexInput.vertexBindingDescriptionCount = 0;
|
||||
vertexInput.vertexAttributeDescriptionCount = 0;
|
||||
VertexInputStateBuilder vertexInputBuilder;
|
||||
const auto& vertexInput = vertexInputBuilder.Build();
|
||||
|
||||
VkPipelineInputAssemblyStateCreateInfo ia{VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO};
|
||||
ia.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
|
||||
@@ -444,7 +444,12 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
m_frameContext.EndCommandRecording();
|
||||
}
|
||||
|
||||
void VulkanRenderer::DrawArrays(GLenum mode, GLint first, GLsizei count) {
|
||||
void VulkanRenderer::DrawArrays(const DrawArrayPayload& payload) {
|
||||
if (payload.mode != GL_TRIANGLES) {
|
||||
MGLOG_W("DrawArrays skipped: primitive mode %u is not supported yet", payload.mode);
|
||||
return;
|
||||
}
|
||||
|
||||
EnsureFrameRecordingStarted();
|
||||
auto& frame = m_frameContext.GetCurrent();
|
||||
if (!frame.isCommandRecording || !m_isMainRenderPassActive) {
|
||||
@@ -471,7 +476,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
scissor.extent = swapchainExtent;
|
||||
vkCmdSetScissor(commandBuffer, 0, 1, &scissor);
|
||||
|
||||
vkCmdDraw(commandBuffer, static_cast<Uint32>(count), 1, static_cast<Uint32>(first), 0);
|
||||
vkCmdDraw(commandBuffer, static_cast<Uint32>(payload.count), 1, static_cast<Uint32>(payload.first), 0);
|
||||
}
|
||||
|
||||
void VulkanRenderer::DrawElements(GLenum type, GLsizei count, const void* indexData, SizeT indexDataSizeBytes) {
|
||||
|
||||
@@ -19,6 +19,20 @@
|
||||
#include "../VkIncludes.h"
|
||||
|
||||
namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
struct DrawArrayPayload {
|
||||
GLenum mode = GL_TRIANGLES;
|
||||
GLint first = 0;
|
||||
GLsizei count = 0;
|
||||
Bool hasPositionStream = false;
|
||||
const void* positionData = nullptr;
|
||||
SizeT positionDataSizeBytes = 0;
|
||||
SizeT positionStrideBytes = 0;
|
||||
SizeT positionOffsetBytes = 0;
|
||||
GLenum positionType = GL_FLOAT;
|
||||
GLint positionSize = 0;
|
||||
Bool positionNormalized = false;
|
||||
};
|
||||
|
||||
class VulkanRenderer {
|
||||
public:
|
||||
VulkanRenderer(NativeWindowType window, const VulkanRendererConfig& cfg = {});
|
||||
@@ -30,7 +44,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
void RequestClear(GLbitfield mask, const FloatVec4& color, Float depth, Uint32 stencil);
|
||||
Bool ConsumePendingColorClear(VkClearColorValue& outClearColor);
|
||||
void EnsureFrameRecordingStarted();
|
||||
void DrawArrays(GLenum mode, GLint first, GLsizei count);
|
||||
void DrawArrays(const DrawArrayPayload& payload);
|
||||
void DrawElements(GLenum type, GLsizei count, const void* indexData, SizeT indexDataSizeBytes);
|
||||
void Render();
|
||||
void Present();
|
||||
|
||||
Reference in New Issue
Block a user