Add proper support for IndexType and uint32 indices

This commit is contained in:
SirLynix
2022-04-04 09:02:00 +02:00
parent 66ff6cfa81
commit 9d526741b9
34 changed files with 188 additions and 57 deletions

View File

@@ -39,6 +39,7 @@ namespace Nz
throw std::runtime_error("failed to fill index buffer");
submeshData.indexCount = indexBuffer->GetIndexCount();
submeshData.indexType = indexBuffer->GetIndexType();
submeshData.vertexBuffer = renderDevice->InstantiateBuffer(BufferType::Vertex, vertexBuffer->GetStride() * vertexBuffer->GetVertexCount(), BufferUsage::DeviceLocal | BufferUsage::Write);
if (!submeshData.vertexBuffer->Fill(vertexBufferContent->GetData() + vertexBuffer->GetStartOffset(), 0, vertexBuffer->GetEndOffset() - vertexBuffer->GetStartOffset()))

View File

@@ -46,7 +46,10 @@ namespace Nz
const auto& vertexBuffer = m_graphicalMesh->GetVertexBuffer(i);
const auto& renderPipeline = materialPass->GetPipeline()->GetRenderPipeline(submeshData.vertexBufferData);
elements.emplace_back(std::make_unique<RenderSubmesh>(GetRenderLayer(), materialPass, renderPipeline, worldInstance, m_graphicalMesh->GetIndexCount(i), indexBuffer, vertexBuffer, scissorBox));
std::size_t indexCount = m_graphicalMesh->GetIndexCount(i);
IndexType indexType = m_graphicalMesh->GetIndexType(i);
elements.emplace_back(std::make_unique<RenderSubmesh>(GetRenderLayer(), materialPass, renderPipeline, worldInstance, indexCount, indexType, indexBuffer, vertexBuffer, scissorBox));
}
}

View File

@@ -275,7 +275,7 @@ namespace Nz
{
auto& data = static_cast<SpriteChainRendererData&>(rendererData);
commandBuffer.BindIndexBuffer(*m_indexBuffer);
commandBuffer.BindIndexBuffer(*m_indexBuffer, Nz::IndexType::U16);
Vector2f targetSize = viewerInstance.GetTargetSize();
Recti fullscreenScissorBox(0, 0, SafeCast<int>(std::floor(targetSize.x)), SafeCast<int>(std::floor(targetSize.y)));

View File

@@ -169,6 +169,7 @@ namespace Nz
drawCall.firstIndex = 0;
drawCall.indexBuffer = currentIndexBuffer;
drawCall.indexCount = submesh.GetIndexCount();
drawCall.indexType = submesh.GetIndexType();
drawCall.renderPipeline = currentPipeline;
drawCall.scissorBox = currentScissorBox;
drawCall.shaderBinding = currentShaderBinding;
@@ -217,7 +218,7 @@ namespace Nz
if (currentIndexBuffer != drawData.indexBuffer)
{
commandBuffer.BindIndexBuffer(*drawData.indexBuffer);
commandBuffer.BindIndexBuffer(*drawData.indexBuffer, drawData.indexType);
currentIndexBuffer = drawData.indexBuffer;
}

View File

@@ -105,9 +105,17 @@ namespace Nz
else if constexpr (std::is_same_v<T, DrawIndexedData>)
{
const UInt8* origin = 0; //< For an easy way to cast an integer to a pointer
origin += command.states.indexBufferOffset;
switch (command.states.indexBufferType)
{
case IndexType::U8: origin += command.firstIndex * sizeof(UInt8); break;
case IndexType::U16: origin += command.firstIndex * sizeof(UInt16); break;
case IndexType::U32: origin += command.firstIndex * sizeof(UInt32); break;
}
ApplyStates(*context, command.states);
context->glDrawElementsInstanced(ToOpenGL(command.states.pipeline->GetPipelineInfo().primitiveMode), command.indexCount, GL_UNSIGNED_SHORT, origin + command.firstIndex * sizeof(UInt16), command.instanceCount);
context->glDrawElementsInstanced(ToOpenGL(command.states.pipeline->GetPipelineInfo().primitiveMode), command.indexCount, ToOpenGL(command.states.indexBufferType), origin, command.instanceCount);
}
else if constexpr (std::is_same_v<T, EndDebugRegionData>)
{

View File

@@ -25,11 +25,11 @@ namespace Nz
m_commandBuffer.SetFramebuffer(static_cast<const OpenGLFramebuffer&>(framebuffer), static_cast<const OpenGLRenderPass&>(renderPass), clearValues, clearValueCount);
}
void OpenGLCommandBufferBuilder::BindIndexBuffer(const RenderBuffer& indexBuffer, UInt64 offset)
void OpenGLCommandBufferBuilder::BindIndexBuffer(const RenderBuffer& indexBuffer, IndexType indexType, UInt64 offset)
{
const OpenGLBuffer& glBuffer = static_cast<const OpenGLBuffer&>(indexBuffer);
m_commandBuffer.BindIndexBuffer(glBuffer.GetBuffer().GetObjectId(), offset);
m_commandBuffer.BindIndexBuffer(glBuffer.GetBuffer().GetObjectId(), indexType, offset);
}
void OpenGLCommandBufferBuilder::BindPipeline(const RenderPipeline& pipeline)

View File

@@ -170,7 +170,7 @@ namespace Nz
});
std::shared_ptr<VertexBuffer> colliderVB = std::make_shared<VertexBuffer>(VertexDeclaration::Get(VertexLayout::XYZ), colliderVertices.size(), BufferUsage::Write, SoftwareBufferFactory, colliderVertices.data());
std::shared_ptr<IndexBuffer> colliderIB = std::make_shared<IndexBuffer>(false, colliderIndices.size(), BufferUsage::Write, SoftwareBufferFactory, colliderIndices.data());
std::shared_ptr<IndexBuffer> colliderIB = std::make_shared<IndexBuffer>(IndexType::U16, colliderIndices.size(), BufferUsage::Write, SoftwareBufferFactory, colliderIndices.data());
std::shared_ptr<StaticMesh> colliderSubMesh = std::make_shared<StaticMesh>(std::move(colliderVB), std::move(colliderIB));
colliderSubMesh->GenerateAABB();

View File

@@ -108,7 +108,7 @@ namespace Nz
}
}
std::shared_ptr<IndexBuffer> indexBuffer = std::make_shared<IndexBuffer>(false, 3 * header.num_tris, parameters.indexBufferFlags, parameters.bufferFactory);
std::shared_ptr<IndexBuffer> indexBuffer = std::make_shared<IndexBuffer>(IndexType::U16, 3 * header.num_tris, parameters.indexBufferFlags, parameters.bufferFactory);
// Extract triangles data
std::vector<MD2_Triangle> triangles(header.num_tris);

View File

@@ -96,7 +96,7 @@ namespace Nz
bool largeIndices = (vertexCount > std::numeric_limits<UInt16>::max());
std::shared_ptr<IndexBuffer> indexBuffer = std::make_shared<IndexBuffer>(largeIndices, indexCount, parameters.indexBufferFlags, parameters.bufferFactory);
std::shared_ptr<IndexBuffer> indexBuffer = std::make_shared<IndexBuffer>((largeIndices) ? IndexType::U32 : IndexType::U16, indexCount, parameters.indexBufferFlags, parameters.bufferFactory);
std::shared_ptr<VertexBuffer> vertexBuffer = std::make_shared<VertexBuffer>(VertexDeclaration::Get(VertexLayout::XYZ_Normal_UV_Tangent_Skinning), UInt32(vertexCount), parameters.vertexBufferFlags, parameters.bufferFactory);
// Index buffer
@@ -241,7 +241,7 @@ namespace Nz
// Index buffer
bool largeIndices = (vertexCount > std::numeric_limits<UInt16>::max());
std::shared_ptr<IndexBuffer> indexBuffer = std::make_shared<IndexBuffer>(largeIndices, indexCount, parameters.indexBufferFlags, parameters.bufferFactory);
std::shared_ptr<IndexBuffer> indexBuffer = std::make_shared<IndexBuffer>((largeIndices) ? IndexType::U32 : IndexType::U16, indexCount, parameters.indexBufferFlags, parameters.bufferFactory);
IndexMapper indexMapper(*indexBuffer);
IndexIterator index = indexMapper.begin();
@@ -293,7 +293,7 @@ namespace Nz
// Vertex colors (.md5mesh files have no vertex color)
if (auto colorPtr = vertexMapper.GetComponentPtr<Color>(VertexComponent::Color))
{
for (std::size_t i = 0; i < md5Mesh.vertices.size(); ++i)
for (std::size_t j = 0; j < md5Mesh.vertices.size(); ++j)
*colorPtr++ = Color::White;
}

View File

@@ -254,7 +254,9 @@ namespace Nz
}
// Création des buffers
std::shared_ptr<IndexBuffer> indexBuffer = std::make_shared<IndexBuffer>(vertexCount > std::numeric_limits<UInt16>::max(), indices.size(), parameters.indexBufferFlags, parameters.bufferFactory);
bool largeIndices = (vertexCount > std::numeric_limits<UInt16>::max());
std::shared_ptr<IndexBuffer> indexBuffer = std::make_shared<IndexBuffer>((largeIndices) ? IndexType::U32 : IndexType::U16, indices.size(), parameters.indexBufferFlags, parameters.bufferFactory);
std::shared_ptr<VertexBuffer> vertexBuffer = std::make_shared<VertexBuffer>(parameters.vertexDeclaration, vertexCount, parameters.vertexBufferFlags, parameters.bufferFactory);
// Remplissage des indices

View File

@@ -13,11 +13,11 @@
namespace Nz
{
IndexBuffer::IndexBuffer(bool largeIndices, std::shared_ptr<Buffer> buffer) :
IndexBuffer::IndexBuffer(IndexType indexType, std::shared_ptr<Buffer> buffer) :
m_buffer(std::move(buffer)),
m_indexType(indexType),
m_endOffset(m_buffer->GetSize()),
m_startOffset(0),
m_largeIndices(largeIndices)
m_startOffset(0)
{
NazaraAssert(m_buffer, "invalid buffer");
NazaraAssert(m_buffer->GetType() == BufferType::Index, "buffer must be an index buffer");
@@ -26,23 +26,23 @@ namespace Nz
m_indexCount = m_endOffset / GetStride();
}
IndexBuffer::IndexBuffer(bool largeIndices, std::shared_ptr<Buffer> buffer, UInt64 offset, UInt64 size) :
IndexBuffer::IndexBuffer(IndexType indexType, std::shared_ptr<Buffer> buffer, UInt64 offset, UInt64 size) :
m_buffer(std::move(buffer)),
m_indexType(indexType),
m_endOffset(offset + size),
m_startOffset(offset),
m_largeIndices(largeIndices)
m_startOffset(offset)
{
NazaraAssert(m_buffer, "invalid buffer");
NazaraAssert(m_buffer->GetType() == BufferType::Index, "buffer must be an index buffer");
NazaraAssert(size > 0, "invalid size");
NazaraAssert(size > 0, "invalid buffer size");
m_indexCount = size / GetStride();
}
IndexBuffer::IndexBuffer(bool largeIndices, UInt64 indexCount, BufferUsageFlags usage, const BufferFactory& bufferFactory, const void* initialData) :
IndexBuffer::IndexBuffer(IndexType indexType, UInt64 indexCount, BufferUsageFlags usage, const BufferFactory& bufferFactory, const void* initialData) :
m_indexType(indexType),
m_indexCount(indexCount),
m_startOffset(0),
m_largeIndices(largeIndices)
m_startOffset(0)
{
NazaraAssert(indexCount > 0, "invalid index count");

View File

@@ -19,6 +19,12 @@ namespace Nz
return static_cast<UInt32>(i);
}
UInt32 Getter8(const void* buffer, std::size_t i)
{
const UInt8* ptr = static_cast<const UInt8*>(buffer);
return ptr[i];
}
UInt32 Getter16(const void* buffer, std::size_t i)
{
const UInt16* ptr = static_cast<const UInt16*>(buffer);
@@ -37,10 +43,16 @@ namespace Nz
return 0;
}
void Setter8(void* buffer, std::size_t i, UInt32 value)
{
UInt8* ptr = static_cast<UInt8*>(buffer);
ptr[i] = SafeCast<UInt8>(value);
}
void Setter16(void* buffer, std::size_t i, UInt32 value)
{
UInt16* ptr = static_cast<UInt16*>(buffer);
ptr[i] = static_cast<UInt16>(value);
ptr[i] = SafeCast<UInt16>(value);
}
void Setter32(void* buffer, std::size_t i, UInt32 value)
@@ -63,13 +75,37 @@ namespace Nz
if (!m_mapper.Map(indexBuffer, 0, m_indexCount))
NazaraError("Failed to map buffer"); ///TODO: Unexcepted
Getter rightGetter = nullptr;
Setter rightSetter = nullptr;
switch (indexBuffer.GetIndexType())
{
case IndexType::U8:
rightGetter = Getter8;
rightSetter = Setter8;
break;
case IndexType::U16:
rightGetter = Getter16;
rightSetter = Setter16;
break;
case IndexType::U32:
rightGetter = Getter32;
rightSetter = Setter32;
break;
}
if (!rightGetter)
NazaraError("unexpected index size"); ///TODO: Unexcepted
if (indexBuffer.GetBuffer()->GetUsageFlags().Test(BufferUsage::Read))
m_getter = (indexBuffer.HasLargeIndices()) ? Getter32 : Getter16;
m_getter = rightGetter;
else
m_getter = GetterError;
if (indexBuffer.GetBuffer()->GetUsageFlags().Test(BufferUsage::Write))
m_setter = (indexBuffer.HasLargeIndices()) ? Setter32 : Setter16;
m_setter = rightSetter;
else
m_setter = SetterError;
}

View File

@@ -100,7 +100,9 @@ namespace Nz
std::size_t vertexCount;
ComputeBoxIndexVertexCount(primitive.box.subdivision, &indexCount, &vertexCount);
indexBuffer = std::make_shared<IndexBuffer>(vertexCount > std::numeric_limits<UInt16>::max(), indexCount, params.indexBufferFlags, params.bufferFactory);
bool largeIndices = (vertexCount > std::numeric_limits<UInt16>::max());
indexBuffer = std::make_shared<IndexBuffer>((largeIndices) ? IndexType::U32 : IndexType::U16, indexCount, params.indexBufferFlags, params.bufferFactory);
vertexBuffer = std::make_shared<VertexBuffer>(declaration, vertexCount, params.vertexBufferFlags, params.bufferFactory);
VertexMapper vertexMapper(*vertexBuffer);
@@ -122,7 +124,9 @@ namespace Nz
std::size_t vertexCount;
ComputeConeIndexVertexCount(primitive.cone.subdivision, &indexCount, &vertexCount);
indexBuffer = std::make_shared<IndexBuffer>(vertexCount > std::numeric_limits<UInt16>::max(), indexCount, params.indexBufferFlags, params.bufferFactory);
bool largeIndices = (vertexCount > std::numeric_limits<UInt16>::max());
indexBuffer = std::make_shared<IndexBuffer>((largeIndices) ? IndexType::U32 : IndexType::U16, indexCount, params.indexBufferFlags, params.bufferFactory);
vertexBuffer = std::make_shared<VertexBuffer>(declaration, vertexCount, params.vertexBufferFlags, params.bufferFactory);
VertexMapper vertexMapper(*vertexBuffer);
@@ -144,7 +148,9 @@ namespace Nz
std::size_t vertexCount;
ComputePlaneIndexVertexCount(primitive.plane.subdivision, &indexCount, &vertexCount);
indexBuffer = std::make_shared<IndexBuffer>(vertexCount > std::numeric_limits<UInt16>::max(), indexCount, params.indexBufferFlags, params.bufferFactory);
bool largeIndices = (vertexCount > std::numeric_limits<UInt16>::max());
indexBuffer = std::make_shared<IndexBuffer>((largeIndices) ? IndexType::U32 : IndexType::U16, indexCount, params.indexBufferFlags, params.bufferFactory);
vertexBuffer = std::make_shared<VertexBuffer>(declaration, vertexCount, params.vertexBufferFlags, params.bufferFactory);
VertexMapper vertexMapper(*vertexBuffer);
@@ -170,7 +176,9 @@ namespace Nz
std::size_t vertexCount;
ComputeCubicSphereIndexVertexCount(primitive.sphere.cubic.subdivision, &indexCount, &vertexCount);
indexBuffer = std::make_shared<IndexBuffer>(vertexCount > std::numeric_limits<UInt16>::max(), indexCount, params.indexBufferFlags, params.bufferFactory);
bool largeIndices = (vertexCount > std::numeric_limits<UInt16>::max());
indexBuffer = std::make_shared<IndexBuffer>((largeIndices) ? IndexType::U32 : IndexType::U16, indexCount, params.indexBufferFlags, params.bufferFactory);
vertexBuffer = std::make_shared<VertexBuffer>(declaration, vertexCount, params.vertexBufferFlags, params.bufferFactory);
VertexMapper vertexMapper(*vertexBuffer);
@@ -192,7 +200,9 @@ namespace Nz
std::size_t vertexCount;
ComputeIcoSphereIndexVertexCount(primitive.sphere.ico.recursionLevel, &indexCount, &vertexCount);
indexBuffer = std::make_shared<IndexBuffer>(vertexCount > std::numeric_limits<UInt16>::max(), indexCount, params.indexBufferFlags, params.bufferFactory);
bool largeIndices = (vertexCount > std::numeric_limits<UInt16>::max());
indexBuffer = std::make_shared<IndexBuffer>((largeIndices) ? IndexType::U32 : IndexType::U16, indexCount, params.indexBufferFlags, params.bufferFactory);
vertexBuffer = std::make_shared<VertexBuffer>(declaration, vertexCount, params.vertexBufferFlags, params.bufferFactory);
VertexMapper vertexMapper(*vertexBuffer);
@@ -214,7 +224,9 @@ namespace Nz
std::size_t vertexCount;
ComputeUvSphereIndexVertexCount(primitive.sphere.uv.sliceCount, primitive.sphere.uv.stackCount, &indexCount, &vertexCount);
indexBuffer = std::make_shared<IndexBuffer>(vertexCount > std::numeric_limits<UInt16>::max(), indexCount, params.indexBufferFlags, params.bufferFactory);
bool largeIndices = (vertexCount > std::numeric_limits<UInt16>::max());
indexBuffer = std::make_shared<IndexBuffer>((largeIndices) ? IndexType::U32 : IndexType::U16, indexCount, params.indexBufferFlags, params.bufferFactory);
vertexBuffer = std::make_shared<VertexBuffer>(declaration, vertexCount, params.vertexBufferFlags, params.bufferFactory);
VertexMapper vertexMapper(*vertexBuffer);

View File

@@ -72,11 +72,11 @@ namespace Nz
m_currentSubpassIndex = 0;
}
void VulkanCommandBufferBuilder::BindIndexBuffer(const RenderBuffer& indexBuffer, UInt64 offset)
void VulkanCommandBufferBuilder::BindIndexBuffer(const RenderBuffer& indexBuffer, IndexType indexType, UInt64 offset)
{
const VulkanBuffer& vkBuffer = static_cast<const VulkanBuffer&>(indexBuffer);
m_commandBuffer.BindIndexBuffer(vkBuffer.GetBuffer(), offset, VK_INDEX_TYPE_UINT16); //< Fuck me right?
m_commandBuffer.BindIndexBuffer(vkBuffer.GetBuffer(), offset, ToVulkan(indexType));
}
void VulkanCommandBufferBuilder::BindPipeline(const RenderPipeline& pipeline)