mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-11 21:58:31 +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.program = currentProgram ? currentProgram.get() : nullptr;
|
||||||
payload.drawArray.vertexArray = vao.get();
|
payload.drawArray.vertexArray = vao.get();
|
||||||
payload.indexType = type;
|
payload.indexType = type;
|
||||||
payload.indexData = indexData->data() + byteOffset;
|
payload.indexByteOffset = 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pVulkanRenderer->DrawElements(payload);
|
pVulkanRenderer->DrawElements(payload);
|
||||||
}
|
}
|
||||||
@@ -163,31 +138,6 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
|
|
||||||
const auto vao = MG_State::pGLContext->GetBoundVertexArray();
|
const auto vao = MG_State::pGLContext->GetBoundVertexArray();
|
||||||
payload.vertexArray = vao ? vao.get() : nullptr;
|
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);
|
pVulkanRenderer->DrawArrays(payload);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -571,7 +571,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
|
|
||||||
Bool VulkanRenderer::UploadAndBindVertexStreams(
|
Bool VulkanRenderer::UploadAndBindVertexStreams(
|
||||||
const VertexInputStateFactory::BackendVertexInputState& vertexInputState,
|
const VertexInputStateFactory::BackendVertexInputState& vertexInputState,
|
||||||
const MG_State::GLState::VertexArrayObject& vertexArray,
|
const DrawArrayPayload& payload,
|
||||||
VkCommandBuffer commandBuffer) {
|
VkCommandBuffer commandBuffer) {
|
||||||
if (vertexInputState.bindings.empty()) {
|
if (vertexInputState.bindings.empty()) {
|
||||||
return true;
|
return true;
|
||||||
@@ -590,19 +590,27 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
Vector<VkBuffer> vkBuffers(bindingCount, VK_NULL_HANDLE);
|
Vector<VkBuffer> vkBuffers(bindingCount, VK_NULL_HANDLE);
|
||||||
Vector<VkDeviceSize> vkOffsets(bindingCount, 0);
|
Vector<VkDeviceSize> vkOffsets(bindingCount, 0);
|
||||||
|
|
||||||
for (SizeT binding = 0; binding < bindingCount; ++binding) {
|
auto findBufferByKey = [&](SizeT bufferKey) -> const MG_State::GLState::BufferObject* {
|
||||||
const SizeT bufferKey = vertexInputState.bindingBufferKeys[binding];
|
if (!payload.vertexArray) {
|
||||||
const MG_State::GLState::BufferObject* sourceBuffer = nullptr;
|
return nullptr;
|
||||||
|
}
|
||||||
|
const auto& attrs = payload.vertexArray->GetAllAttributes();
|
||||||
for (Uint32 location = 0; location < MG_State::GLState::VertexArrayObject::MAX_VERTEX_ATTRIBS; ++location) {
|
for (Uint32 location = 0; location < MG_State::GLState::VertexArrayObject::MAX_VERTEX_ATTRIBS; ++location) {
|
||||||
const auto& attr = vertexArray.GetAttribute(location);
|
const auto& attr = attrs[location];
|
||||||
if (!attr.Enabled || !attr.Buffer) {
|
if (!attr.Buffer) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (reinterpret_cast<SizeT>(attr.Buffer.get()) == bufferKey) {
|
const auto* buffer = attr.Buffer.get();
|
||||||
sourceBuffer = attr.Buffer.get();
|
if (reinterpret_cast<SizeT>(buffer) == bufferKey) {
|
||||||
break;
|
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) {
|
if (!sourceBuffer) {
|
||||||
MGLOG_W("UploadAndBindVertexStreams skipped: no source buffer for binding %zu", binding);
|
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");
|
MGLOG_W("DrawArrays skipped: vertex input requires VAO");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!UploadAndBindVertexStreams(*vertexInputState, *payload.vertexArray, commandBuffer)) {
|
if (!UploadAndBindVertexStreams(*vertexInputState, payload, commandBuffer)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -757,8 +765,25 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
MOBILEGL_ASSERT(payload.indexData != nullptr, "DrawElements requires non-null indexData");
|
if (payload.drawArray.vertexArray == nullptr) {
|
||||||
MOBILEGL_ASSERT(payload.indexDataSizeBytes > 0, "DrawElements requires non-zero index data size");
|
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;
|
const VertexInputStateFactory::BackendVertexInputState* vertexInputState = nullptr;
|
||||||
if (payload.drawArray.vertexArray && m_vertexInputStateFactory) {
|
if (payload.drawArray.vertexArray && m_vertexInputStateFactory) {
|
||||||
@@ -794,10 +819,10 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_indexBuffer.IsValid() || m_indexBuffer.GetSize() < payload.indexDataSizeBytes) {
|
if (!m_indexBuffer.IsValid() || m_indexBuffer.GetSize() < indexDataSizeBytes) {
|
||||||
DeferDestroyBuffer(m_indexBuffer);
|
DeferDestroyBuffer(m_indexBuffer);
|
||||||
const Bool created = m_indexBuffer.Create(
|
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,
|
VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
|
||||||
VMA_MEMORY_USAGE_AUTO,
|
VMA_MEMORY_USAGE_AUTO,
|
||||||
VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT);
|
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");
|
MGLOG_E("DrawElements skipped: failed to upload index data");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -829,7 +855,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
MGLOG_W("DrawElements skipped: vertex input requires VAO");
|
MGLOG_W("DrawElements skipped: vertex input requires VAO");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!UploadAndBindVertexStreams(*vertexInputState, *payload.drawArray.vertexArray, commandBuffer)) {
|
if (!UploadAndBindVertexStreams(*vertexInputState, payload.drawArray, commandBuffer)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,21 +35,12 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
GLsizei count = 0;
|
GLsizei count = 0;
|
||||||
const MG_State::GLState::ProgramObject* program = nullptr;
|
const MG_State::GLState::ProgramObject* program = nullptr;
|
||||||
const MG_State::GLState::VertexArrayObject* vertexArray = 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 {
|
struct DrawElementPayload {
|
||||||
DrawArrayPayload drawArray;
|
DrawArrayPayload drawArray;
|
||||||
GLenum indexType = GL_UNSIGNED_SHORT;
|
GLenum indexType = GL_UNSIGNED_SHORT;
|
||||||
const void* indexData = nullptr;
|
SizeT indexByteOffset = 0;
|
||||||
SizeT indexDataSizeBytes = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class VulkanRenderer {
|
class VulkanRenderer {
|
||||||
@@ -185,7 +176,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
void CollectDeferredBufferReleases(Uint32 frameIndex);
|
void CollectDeferredBufferReleases(Uint32 frameIndex);
|
||||||
Bool UploadAndBindVertexStreams(
|
Bool UploadAndBindVertexStreams(
|
||||||
const VertexInputStateFactory::BackendVertexInputState& vertexInputState,
|
const VertexInputStateFactory::BackendVertexInputState& vertexInputState,
|
||||||
const MG_State::GLState::VertexArrayObject& vertexArray,
|
const DrawArrayPayload& payload,
|
||||||
VkCommandBuffer commandBuffer);
|
VkCommandBuffer commandBuffer);
|
||||||
|
|
||||||
void ShutdownSwapchain();
|
void ShutdownSwapchain();
|
||||||
|
|||||||
Reference in New Issue
Block a user