mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-08 04:08:32 +09:00
[Chore] (MG_Backend/DirectVulkan): simplifying draw payload
This commit is contained in:
@@ -101,32 +101,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
payload.drawArray.program = currentProgram ? currentProgram.get() : nullptr;
|
||||
payload.drawArray.vertexArray = vao.get();
|
||||
payload.indexType = type;
|
||||
payload.indexData = indexData->data() + byteOffset;
|
||||
payload.indexDataSizeBytes = requiredBytes;
|
||||
|
||||
const auto& attr0 = vao->GetAttribute(0);
|
||||
if (attr0.Enabled && attr0.Buffer) {
|
||||
const auto positionData = attr0.Buffer->GetDataReadOnly();
|
||||
if (positionData && !positionData->empty()) {
|
||||
payload.drawArray.hasPositionStream = true;
|
||||
payload.drawArray.positionData = positionData->data();
|
||||
payload.drawArray.positionDataSizeBytes = attr0.Buffer->GetSize();
|
||||
payload.drawArray.positionOffsetBytes = attr0.Offset;
|
||||
payload.drawArray.positionStrideBytes = attr0.Stride > 0 ? static_cast<SizeT>(attr0.Stride) : 0;
|
||||
payload.drawArray.positionSize = attr0.Size;
|
||||
payload.drawArray.positionNormalized = attr0.Normalized;
|
||||
|
||||
switch (attr0.Type) {
|
||||
case DataType::Float32:
|
||||
payload.drawArray.positionType = GL_FLOAT;
|
||||
break;
|
||||
default:
|
||||
payload.drawArray.positionType = GL_FLOAT;
|
||||
payload.drawArray.hasPositionStream = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
payload.indexByteOffset = byteOffset;
|
||||
|
||||
pVulkanRenderer->DrawElements(payload);
|
||||
}
|
||||
@@ -163,31 +138,6 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
|
||||
const auto vao = MG_State::pGLContext->GetBoundVertexArray();
|
||||
payload.vertexArray = vao ? vao.get() : nullptr;
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -571,7 +571,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
|
||||
Bool VulkanRenderer::UploadAndBindVertexStreams(
|
||||
const VertexInputStateFactory::BackendVertexInputState& vertexInputState,
|
||||
const MG_State::GLState::VertexArrayObject& vertexArray,
|
||||
const DrawArrayPayload& payload,
|
||||
VkCommandBuffer commandBuffer) {
|
||||
if (vertexInputState.bindings.empty()) {
|
||||
return true;
|
||||
@@ -590,19 +590,27 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
Vector<VkBuffer> vkBuffers(bindingCount, VK_NULL_HANDLE);
|
||||
Vector<VkDeviceSize> vkOffsets(bindingCount, 0);
|
||||
|
||||
for (SizeT binding = 0; binding < bindingCount; ++binding) {
|
||||
const SizeT bufferKey = vertexInputState.bindingBufferKeys[binding];
|
||||
const MG_State::GLState::BufferObject* sourceBuffer = nullptr;
|
||||
auto findBufferByKey = [&](SizeT bufferKey) -> const MG_State::GLState::BufferObject* {
|
||||
if (!payload.vertexArray) {
|
||||
return nullptr;
|
||||
}
|
||||
const auto& attrs = payload.vertexArray->GetAllAttributes();
|
||||
for (Uint32 location = 0; location < MG_State::GLState::VertexArrayObject::MAX_VERTEX_ATTRIBS; ++location) {
|
||||
const auto& attr = vertexArray.GetAttribute(location);
|
||||
if (!attr.Enabled || !attr.Buffer) {
|
||||
const auto& attr = attrs[location];
|
||||
if (!attr.Buffer) {
|
||||
continue;
|
||||
}
|
||||
if (reinterpret_cast<SizeT>(attr.Buffer.get()) == bufferKey) {
|
||||
sourceBuffer = attr.Buffer.get();
|
||||
break;
|
||||
const auto* buffer = attr.Buffer.get();
|
||||
if (reinterpret_cast<SizeT>(buffer) == bufferKey) {
|
||||
return buffer;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
};
|
||||
|
||||
for (SizeT binding = 0; binding < bindingCount; ++binding) {
|
||||
const SizeT bufferKey = vertexInputState.bindingBufferKeys[binding];
|
||||
const MG_State::GLState::BufferObject* sourceBuffer = findBufferByKey(bufferKey);
|
||||
|
||||
if (!sourceBuffer) {
|
||||
MGLOG_W("UploadAndBindVertexStreams skipped: no source buffer for binding %zu", binding);
|
||||
@@ -709,7 +717,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
MGLOG_W("DrawArrays skipped: vertex input requires VAO");
|
||||
return;
|
||||
}
|
||||
if (!UploadAndBindVertexStreams(*vertexInputState, *payload.vertexArray, commandBuffer)) {
|
||||
if (!UploadAndBindVertexStreams(*vertexInputState, payload, commandBuffer)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -757,8 +765,25 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
return;
|
||||
}
|
||||
|
||||
MOBILEGL_ASSERT(payload.indexData != nullptr, "DrawElements requires non-null indexData");
|
||||
MOBILEGL_ASSERT(payload.indexDataSizeBytes > 0, "DrawElements requires non-zero index data size");
|
||||
if (payload.drawArray.vertexArray == nullptr) {
|
||||
MGLOG_W("DrawElements skipped: no VAO provided");
|
||||
return;
|
||||
}
|
||||
|
||||
// VertexArrayObject currently exposes index-buffer binding through non-const accessor.
|
||||
auto* vao = const_cast<MG_State::GLState::VertexArrayObject*>(payload.drawArray.vertexArray);
|
||||
const auto indexBuffer = vao->GetIndexBufferBindingSlot().GetBoundObject();
|
||||
if (!indexBuffer) {
|
||||
MGLOG_W("DrawElements skipped: VAO has no bound ELEMENT_ARRAY_BUFFER");
|
||||
return;
|
||||
}
|
||||
|
||||
const auto indexData = indexBuffer->GetDataReadOnly();
|
||||
MOBILEGL_ASSERT(indexData != nullptr && !indexData->empty(), "DrawElements requires non-empty EBO data");
|
||||
const SizeT indexSize = (payload.indexType == GL_UNSIGNED_SHORT) ? sizeof(Uint16) : sizeof(Uint32);
|
||||
const SizeT indexDataSizeBytes = static_cast<SizeT>(payload.drawArray.count) * indexSize;
|
||||
MOBILEGL_ASSERT(payload.indexByteOffset + indexDataSizeBytes <= indexBuffer->GetSize(),
|
||||
"DrawElements index range out of bounds");
|
||||
|
||||
const VertexInputStateFactory::BackendVertexInputState* vertexInputState = nullptr;
|
||||
if (payload.drawArray.vertexArray && m_vertexInputStateFactory) {
|
||||
@@ -794,10 +819,10 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_indexBuffer.IsValid() || m_indexBuffer.GetSize() < payload.indexDataSizeBytes) {
|
||||
if (!m_indexBuffer.IsValid() || m_indexBuffer.GetSize() < indexDataSizeBytes) {
|
||||
DeferDestroyBuffer(m_indexBuffer);
|
||||
const Bool created = m_indexBuffer.Create(
|
||||
m_allocator, static_cast<VkDeviceSize>(payload.indexDataSizeBytes),
|
||||
m_allocator, static_cast<VkDeviceSize>(indexDataSizeBytes),
|
||||
VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
|
||||
VMA_MEMORY_USAGE_AUTO,
|
||||
VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT);
|
||||
@@ -807,7 +832,8 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_indexBuffer.Upload(payload.indexData, static_cast<VkDeviceSize>(payload.indexDataSizeBytes), 0)) {
|
||||
if (!m_indexBuffer.Upload(indexData->data() + payload.indexByteOffset, static_cast<VkDeviceSize>(indexDataSizeBytes),
|
||||
0)) {
|
||||
MGLOG_E("DrawElements skipped: failed to upload index data");
|
||||
return;
|
||||
}
|
||||
@@ -829,7 +855,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
MGLOG_W("DrawElements skipped: vertex input requires VAO");
|
||||
return;
|
||||
}
|
||||
if (!UploadAndBindVertexStreams(*vertexInputState, *payload.drawArray.vertexArray, commandBuffer)) {
|
||||
if (!UploadAndBindVertexStreams(*vertexInputState, payload.drawArray, commandBuffer)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,21 +35,12 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
GLsizei count = 0;
|
||||
const MG_State::GLState::ProgramObject* program = nullptr;
|
||||
const MG_State::GLState::VertexArrayObject* vertexArray = nullptr;
|
||||
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;
|
||||
};
|
||||
|
||||
struct DrawElementPayload {
|
||||
DrawArrayPayload drawArray;
|
||||
GLenum indexType = GL_UNSIGNED_SHORT;
|
||||
const void* indexData = nullptr;
|
||||
SizeT indexDataSizeBytes = 0;
|
||||
SizeT indexByteOffset = 0;
|
||||
};
|
||||
|
||||
class VulkanRenderer {
|
||||
@@ -185,7 +176,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
void CollectDeferredBufferReleases(Uint32 frameIndex);
|
||||
Bool UploadAndBindVertexStreams(
|
||||
const VertexInputStateFactory::BackendVertexInputState& vertexInputState,
|
||||
const MG_State::GLState::VertexArrayObject& vertexArray,
|
||||
const DrawArrayPayload& payload,
|
||||
VkCommandBuffer commandBuffer);
|
||||
|
||||
void ShutdownSwapchain();
|
||||
|
||||
Reference in New Issue
Block a user